首页 > 代码库 > 第六章:Python基础の反射与常用模块解密

第六章:Python基础の反射与常用模块解密

本課主題

  • 反射 Mapping 介绍和操作实战
  • 模块介绍和操作实战
  • random 模块
  • time 和 datetime 模块
  • logging 模块
  • sys 模块
  • os 模块
  • hashlib 模块
  • re 模块
  • 本周作业

反射 Mapping 介绍和操作实战

反射是利用字符串的形式去对象 (模块) 中操作 (寻找/检查) 成员

 

 

案例例子

假设创建了一个common.py 程序里而有3个功能,比如网站里的登录页面、主页页面还有登出页面都是不同的页面,要显示的内容都不一样。

技术分享
def login():    print("Login Page")def logout():    print("Logout Page")def home():    print("HomePage")
common.py

再创建一个py程序:index.py,程序一般是做一个判断然后会基于调用不同的功能来返回不同的结果(参考调用方法一的代码)。

技术分享
import common#根据用户不同的输入而返回不同的信息def run():    inp = input("请输入要访问的 url: ")    if inp == "login": # 当用户输入 login,还看到 login 页面        common.login()     elif inp == "logout": # 当用户输入 logout,还看到 logout 页??面        common.logout()     elif inp == "home": # 当用户输入 home,还看到 home 页面        common.home()    else:        print("404")if __name__ == "__main__":    run()
index.py 调用方法一

其实此时可以使用反射的方法(参考调用方法二的代码),直接基于用户输入,

技术分享
# 利用字符串的形式去对象 (模块) 中操作 (寻找/检查) 成员import commondef run():    inp = input("请输入要访问的 url: ")    is_exists = hasattr(common,inp) # 检查用户输入是否在common模块里存在的一个成员    if is_exists:        func = getattr(common, inp) # 到common模块寻找用户输入的一个成员        func()    else:        print("404")if __name__ == "__main__":    run()
index.py 调用方法二

运用 hasattr( ) 和 getattr( )函数来实现,這兩個反射函数分別接收兩個参数(参数一可以是模块, 参数二是参数一的成員)。

hasattr(参数一,参数二) # 到模块里检查成员#参数一可以是模块, 参数二是参数一的成员
getattr(参数一,参数二) # 到模块里寻找成员#参数一可以是模块, 参数二是参数一的成员

 

 

 

模块介绍和操作实战

random 模块

random( ) 函数是用来随机生成数字

技术分享
import randomword_list = []for i in range(6):    random_num = random.randrange(0, 5)    if random_num == 2 or random_num == 4:        num = random.randrange(0, 10)        word_list.append(str(num))    else:        temp = random.randrange(65, 91)        word = chr(temp)        word_list.append(word)words = "".join(word_list)print(words)
random( )函数

time 和 datetime 模块

time

  1. 从1970年1月1号12:00am 开始计算的一个时间戳 Unix timestamp
    技术分享
    import time>>> print(time.time())1473427097.89171
    time.time()
  2. 返回当前系统时间转换成 字符串类型
    技术分享
    import time>>> print(time.ctime()) Fri Sep  9 21:28:13 2016>>> print(time.ctime(time.time()-86400))Thu Sep  8 21:29:06 2016
    time.ctime( )
  3. 返回当前系统时间转换成 struct_time类型
    技术分享
    >>> import time>>> time_obj = time.gmtime() >>> print(time_obj)time.struct_time(tm_year=2016, tm_mon=9, tm_mday=9, tm_hour=13, tm_min=29, tm_sec=41, tm_wday=4, tm_yday=253, tm_isdst=0)>>> print(time_obj.tm_year,time_obj.tm_mon)2016 9>>> type(time_obj)<class time.struct_time>>>> ret = "Year={year} Month={mnth}".format(year=time_obj.tm_year,mnth=time_obj.tm_mon)>>> print(ret)Year=2016 Month=9>>> time_pre_obj = time.gmtime(time.time()-86400) # 返回struct_time类型>>> print(time_pre_obj)time.struct_time(tm_year=2016, tm_mon=9, tm_mday=8, tm_hour=13, tm_min=34, tm_sec=49, tm_wday=3, tm_yday=252, tm_isdst=0)
    time.gmtime( )
  4. 按本地时间来显示时间,并且返回 struct_time类型
    技术分享
    >>> print(time.localtime())time.struct_time(tm_year=2016, tm_mon=9, tm_mday=9, tm_hour=21, tm_min=38, tm_sec=47, tm_wday=4, tm_yday=253, tm_isdst=0)>>> time_obj = time.localtime()>>> print(time_obj)time.struct_time(tm_year=2016, tm_mon=9, tm_mday=9, tm_hour=21, tm_min=38, tm_sec=59, tm_wday=4, tm_yday=253, tm_isdst=0)>>> type(time_obj)<class time.struct_time>
    time.localtime( )
  5. 把一个struct_time类型转换成时间戳
    技术分享
    >>> print(time.mktime(time_obj)) 1473428339.0
    time.mktime( )
  6. 让时间睡眠
    技术分享
    >>> time.sleep(4) >>> print("--------")
    time.sleep( )
  7. 將 struct_time 类型转换成字符串类型 (from struct_time to string)
    技术分享
    >>> print(time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime())) 2016-09-09 13:47:50>>> print(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()))2016-09-09 21:47:51
    time.strftime( )
  8. 將字符串类型转换成 struct_time 类型 (from string to struct_time)
    技术分享
    >>> tm = time.strptime("2016-09-03","%Y-%m-%d")  # 將字符串类型转换成struct_time类型>>> print(tm)time.struct_time(tm_year=2016, tm_mon=9, tm_mday=3, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=5, tm_yday=247, tm_isdst=-1)>>> type(tm)<class time.struct_time>>>> print(time.mktime(tm)) 1472832000.0
    time.strptime( )

Datetime

  1. 输出:2016-09-03
    技术分享
    >>> import datetime>>> d1 = datetime.date.today()>>> print(d1)
    datetime.date.today()
  2. 时间戳直接转成日期格式 2016-08-19
    技术分享
    >>> d2 = datetime.date.fromtimestamp(time.time());>>> print(d2)2016-09-09
    View Code
  3. current time
    技术分享
    >>> current_time = datetime.datetime.now()>>> print(current_time)2016-09-09 21:59:45.125933
    datetime.datetime.now()
  4. 返回  struct_time 类型
    技术分享
    >>> t = current_time.timetuple()>>> print(t)time.struct_time(tm_year=2016, tm_mon=9, tm_mday=9, tm_hour=21, tm_min=59, tm_sec=45, tm_wday=4, tm_yday=253, tm_isdst=-1)>>> type(t)<class time.struct_time>
    timetuple( )
  5. 时间的加减在Python中会调用datetime.timedelta ( )
    技术分享
    >>> d3 = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")>>> print(d3) 2016-09-09 22:03:29>>> new_date = datetime.datetime.now() + datetime.timedelta(days=10)>>> print(new_date)2016-09-19 22:03:38.745696>>> new_hour = datetime.datetime.now() + datetime.timedelta(hours=4)>>> print(new_hour)2016-09-10 02:03:41.642530>>> new_hour = datetime.datetime.now() + datetime.timedelta(hours=4)>>> print(new_hour)2016-09-10 02:03:44.630359
    时间的加减
  6. datetime.datetime.strptime( )
    技术分享
    >>> tm = datetime.datetime.strptime("2016-09-03","%Y-%m-%d")>>> print(tm)2016-09-03 00:00:00
    strptime( )
  7. replace( )
    技术分享
    >>> current_time = datetime.datetime.now()>>> print(current_time)2016-09-09 22:07:10.352970>>> replace_time = current_time.replace(2015,5)>>> print(replace_time)2015-05-09 22:07:10.352970>>> print(type(current_time))<class datetime.datetime>>>> print(type(replace_time))<class datetime.datetime>
    replace( )

Date Format

[更新中]

 

logging 模块

logging 基礎

每个程序都需要有日志记录,日志有几个级别:1. DEBUG; 2.INFO; 3. WARNING; 4.ERROR; 5.CRITICAL

技术分享
import logginglogging.warning("User [alex] attempt wrong password for more than 3 times")logging.critical("Server is down")logging.debug(This message should go to the log file)logging.info(So should this)logging.warning(And this, too)#WARNING:root:User [alex] attempt wrong password for more than 3 times#CRITICAL:root:Server is down#WARNING:root:And this, too
logging

想输出日志到文件可以调用以下函数,filename: 文件名,filemode: 写入模式,level: 日志的级别 (跟这个级别同等或者是比这个更高级别的日志才会写入文件)

logging.basicConfig(filename=‘log.txt‘,filemode=‘w‘,level=logging.INFO)

把 basicConfig 加到程序中然后执行程序,因为日志级别是INFO,所以这里的结果是只有INFO级别或以上的,才会写入log.txt的文件里

技术分享
import logginglogging.basicConfig(filename=log.txt,filemode=w,level=logging.INFO)logging.warning("User [alex] attempt wrong password for more than 3 times")logging.critical("Server is down")logging.debug(This message should go to the log file)logging.info(So should this)logging.warning(And this, too)#log.txt 会有INFO级别或以上的日志"""WARNING:root:User [alex] attempt wrong password for more than 3 timesCRITICAL:root:Server is downINFO:root:So should thisWARNING:root:And this, too"""
Log写进文件的例子

basicConfig可以传入很多不同的参数

logging.basicConfig(filename=‘log.txt‘,                    level=logging.DEBUG,                    format=‘%(asctime)s %(message)s‘,                    datefmt=‘%m/%d/%Y %I:%M:%S %p‘)

 執行

技术分享
import logginglogging.basicConfig(filename=log.txt,                    level=logging.DEBUG,                    format=%(asctime)s %(message)s,                    datefmt=%m/%d/%Y %I:%M:%S %p)logging.warning("User [alex] attempt wrong password for more than 3 times")logging.critical("Server is down")logging.debug(This message should go to the log file)logging.info(So should this)logging.warning(And this, too)# log.tx."""09/09/2016 11:15:35 PM User [alex] attempt wrong password for more than 3 times09/09/2016 11:15:35 PM Server is down09/09/2016 11:15:35 PM This message should go to the log file09/09/2016 11:15:35 PM So should this09/09/2016 11:15:35 PM And this, too"""
Log写进文件的例子二

 

 

 

logging 進階

如果想打印日誌到文件和 Console 上,必需要了解以下概念:

  1. 第一步,创建 Logger,然后设置全区的日志级别。(会比较全区和区部的日志级别,较高的那个会成为该日志输出级别)
    技术分享
    logger = logging.getLogger(TEST-LOG)logger.setLevel(logging.INFO) #configure a global logging level
    logger
  2. 第二步、创建Console Handler 对象,也可以设置 Console 控制台的日志级别,不可以比全区的日志记录级别小,CRITICAL> ERROR> WARNING> INFO> DEBUG。也就是说这两个日志记录级别会比较然后选出最大的那个日志记录级别
    技术分享
    console_handler = logging.StreamHandler() #print the log on the consoleconsole_handler.setLevel(logging.DEBUG)
    console_handler
  3. 第三步、创建File Handler 对象,也可以设置 File Handler 的日志级别。
    技术分享
    file_handler = logging.FileHandler("access.log")file_handler.setLevel(logging.WARNING)
    file_handler
  4. 第四步、创建 Formatter,这是决定输出的格式
    技术分享
    formatter = logging.Formatter(%(asctime)s - %(name)s - %(filename)s - %(levelname)s - %(message)s - %(lineno)s - %(process)d)
    formatter
  5. 第五步、把 Formatter 加到 console_handler 和 file_handler,各自可以有不同的输出格式
    技术分享
    console_handler.setFormatter(formatter)file_handler.setFormatter(formatter)
    setFormatter(formatter)
  6. 第六步、把 Handler 加到 console_handle 和 file_handler 对象里
    技术分享
    logger.addHandler(console_handler)logger.addHandler(file_handler)
    addHandler( )

把以上第1步 到 第6步加起來:

技术分享
import logging #create loggerlogger = logging.getLogger(TEST-LOG)logger.setLevel(logging.INFO) #configure a global logging level # create console handler and set the level to debugconsole_handler = logging.StreamHandler() #print the log on the consoleconsole_handler.setLevel(logging.DEBUG) #override the global logging configuration level and specifiy the configuration on the console# create file handler and set level to warningfile_handler = logging.FileHandler("access.log")file_handler.setLevel(logging.WARNING) #override the global logging configuration level and specifiy the configuration on the file_system# create formatterformatter = logging.Formatter(%(asctime)s - %(name)s - %(filename)s - %(levelname)s - %(message)s - %(lineno)s - %(process)d) # add formatter to ch and fhconsole_handler.setFormatter(formatter)file_handler.setFormatter(formatter) # add console_handler and ffile_handler to logger# 把日志打印到指定的Handler里logger.addHandler(console_handler)logger.addHandler(file_handler) # ‘application‘ codelogger.debug(debug message)logger.info(info message)logger.warn(warn message)logger.error(error message)logger.critical(critical message)# Console"""2016-09-09 23:26:25,907 - TEST-LOG - loggingOps_2.py - INFO - info message - 32 - 11682016-09-09 23:26:25,908 - TEST-LOG - loggingOps_2.py - WARNING - warn message - 33 - 11682016-09-09 23:26:25,909 - TEST-LOG - loggingOps_2.py - ERROR - error message - 34 - 11682016-09-09 23:26:25,910 - TEST-LOG - loggingOps_2.py - CRITICAL - critical message - 35 - 1168"""# access.log"""2016-09-04 00:54:05,713 - TEST-LOG - loggingOps_2.py - WARNING - warn message - 33 - 48272016-09-04 00:54:05,714 - TEST-LOG - loggingOps_2.py - ERROR - error message - 34 - 48272016-09-04 00:54:05,714 - TEST-LOG - loggingOps_2.py - CRITICAL - critical message - 35 - 48272016-09-09 23:26:25,908 - TEST-LOG - loggingOps_2.py - WARNING - warn message - 33 - 11682016-09-09 23:26:25,909 - TEST-LOG - loggingOps_2.py - ERROR - error message - 34 - 11682016-09-09 23:26:25,910 - TEST-LOG - loggingOps_2.py - CRITICAL - critical message - 35 - 1168"""
完整日志代码例子

logging 的參數

[更新中]

 

 

sys 模块

 

 

 

os 模块

 

 

 

hashlib 模块

首先创建一个MD5对象

 

 

re 模块

 

 

本周作业

計算器, +-*/

8*12+(6-(5*6-2)/77+2)*(3-7)+8

需求

  1. 從前到後找,找到第一個(開始)結尾,中間不含有括號
  2. \(中間不包含括號\)
  3. def 處理加減乘除(表達式)
  4. def 處理括號(表達式):
         while True:
               re.split("\(中間不包含括號\)"),表達式,1)

 

參考資料

[金角大王] Python 之路 Day5 - 常用模块学习 http://www.cnblogs.com/alex3714/articles/5161349.html

[銀角大王] Python开发【第六篇】:模块 - http://www.cnblogs.com/wupeiqi/articles/5501365.html

 

第六章:Python基础の反射与常用模块解密