常用模块学习(二)
-
常用模块学习—包及跨模块导入
- 当你的模块文件越来越多,就需要对模块文件进行划分,比如把负责跟数据库交互的都放一个文件夹,把与页面交互相关的放一个文件夹
. └── my_proj ├── crm #代码目录 │ ├── admin.py │ ├── apps.py │ ├── models.py │ ├── tests.py │ └── views.py ├── manage.py └── my_proj #配置文件目录 ├── settings.py ├── urls.py └── wsgi.py
一个文件夹管理多个模块文件,这个文件夹就被称为包
- 那不同包之间的模块怎样互相导入呢?
crm/views.py内容: def sayhi(): print('hello world!') 通过manage.py调用: from crm import views views.sayhi()
用 python2 执行 manage.py: Alexs-MacBook-Pro:my_proj alex$ ls crm manage.py my_proj Alexs-MacBook-Pro:my_proj alex$ python manage.py Traceback (most recent call last): File "manage.py", line 6, in <module> from crm import views ImportError: No module named crm 找不到模块
包就是文件夹,但该文件夹下必须存在 __init__.py 文件, 该文件的内容可以为空。__int__.py用于标识当前文件夹是一个包。
- 在crm目录下创建一个空文件__int__.py ,再执行一次
Alexs-MacBook-Pro:my_proj alex$ touch crm/__init__.py #创建一个空文件 Alexs-MacBook-Pro:my_proj alex$ Alexs-MacBook-Pro:my_proj alex$ ls crm/ __init__.py admin.py models.py views.py __pycache__ apps.py tests.py views.pyc Alexs-MacBook-Pro:my_proj alex$ python manage.py hello world! 注意:在python3里,即使目录下没__int__.py文件也能创建成功,应该是解释器优化所致,但是创建包的时候还是要记得加上这个文件。
- 例:
-
settings.py: DATABASES= { 'host':'localhost' } print('in proj/settings.py') views.py: from proj import settings def sayhi(): print('hello world!') manage.py: from crm import views views.sayhi() 执行 manage.py
- 当你的模块文件越来越多,就需要对模块文件进行划分,比如把负责跟数据库交互的都放一个文件夹,把与页面交互相关的放一个文件夹
-
常用模块学习—跨模块导入2
1 import sys,os 2 3 #sys.path.append("E:/Python/work/myFirstPro/第4章/packages/my_proj/") 4 #print(sys.path) 5 #from proj import settings 6 7 print(dir()) #结果为:['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'os', 'sys'] 8 print(__file__) #结果为:E:/Python/work/myFirstPro/第4章/packages/my_proj/crm/views.py 9 10 #绝对路径 11 DASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) #abspath 绝对路径 12 sys.path.append(DASE_DIR) 13 from proj import settings 14 15 #相对路径 16 # DASE_DIR = os.path.dirname(os.path.dirname(__file__)) #os.path.dirname(__file__) 使目录往上走一层 17 # print(DASE_DIR) #结果为:E:/Python/work/myFirstPro/第4章/packages/my_proj 18 # sys.path.append(DASE_DIR) 19 # from proj import settings #结果为:in proj/settings.py 20 21 def sayhi(): 22 print('hello world!')
-
常用模块学习—相对导入
绝对导入&相对导入 在linux里可以通过cd ..回到上一层目录 ,cd ../.. 往上回2层,这个..就是指相对路径,在python里,导入也可以通过.. 例如: . ├── __init__.py ├── crm │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── models.py │ ├── tests.py │ ├── views.py #from ..proj import settings ├── manage.py └── proj ├── __init__.py ├── settings.py #from .import urls ├── urls.py └── wsgi.py views.py里代码: from ..proj import settings def sayhi(): print('hello world!') print(settings.DATABASES) 执行结果报错了: Traceback (most recent call last): File "my_proj/crm/views.py", line 4, in <module> from ..proj import settings SystemError: Parent module '' not loaded, cannot perform relative import 或者有人会看到这个错 ValueError: attempted relative import beyond top-level package 其实这两个错误的原因归根结底是一样的:在涉及到相对导入时,package所对应的文件夹必须正确的被python解释器视作package,而不是普通文件夹。否则由于不被视作package,无法利用package之间的嵌套关系实现python中包的相对导入。 文件夹被python解释器视作package需要满足两个条件: 1、文件夹中必须有__init__.py文件,该文件可以为空,但必须存在该文件。 2、不能作为顶层模块来执行该文件夹中的py文件(即不能作为主函数的入口)。 解决办法就是,既然你在views.py里执行了相对导入,那就不要把views.py当作入口程序,可以通过上一级的manage.py调用views.py . ├── __init__.py ├── crm │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── models.py │ ├── tests.py │ ├── views.py #from ..proj import settings ├── manage.py #from crm import views └── proj ├── __init__.py ├── settings.py #from .import urls ├── urls.py └── wsgi.py 事实证明还是不行,报错: ValueError: attempted relative import beyond top-level package 但把from ..proj import settings 改成from . import models 后却执行成功了,为什么呢? from .. import models会报错的原因是,这句代码会把manage.py所在的这一层视作package,但实际上它不是,因为package不能是顶层入口代码,若想不出错,只能把manage.py往上再移一层。 正确的代码目录结构如下: packages/ ├── __init__.py ├── manage.py #from my_proj.crm import views └── my_proj ├── crm │ ├── admin.py │ ├── apps.py │ ├── models.py │ ├── tests.py │ ├── views.py #from . import models; from ..proj import settings └── proj ├── __init__.py ├── settings.py ├── urls.py └── wsgi.py 再执行manage.py就不会报错了。 注意:虽然python支持相对导入,但对模块间的路径关系要求比较严格,处理不当就容易出错,so并不建议在项目里经常使用。
-
常用模块学习—time 模块详解
在平常的代码中,我们常常需要与时间打交道。在Python中,与时间处理有关的模块就包括:time,datetime,calendar
-
- 在Python中,通常有这几种方式来表示时间:
- 时间戳
- 格式化的时间字符串
- 元组(struct_time)共九个元素。由于Python的time模块实现主要调用C库,所以各个平台可能有所不同。
- 几个定义
- UTC(Coordinated Universal Time,世界协调时)亦即格林威治天文时间,世界标准时间。在中国为UTC+8。DST(Daylight Saving Time)即夏令时。
- 时间戳(timestamp)的方式:通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行“type(time.time())”,返回的是float类型。
- 元组(struct_time)方式:struct_time元组共有9个元素,返回struct_time的函数主要有gmtime(),localtime(),strptime()。下面列出这种方式元组中的几个元素:
索引(Index) 属性(Attribute) 值(Values) 0 tm_year(年) 比如2011 1 tm_mon(月) 1 - 12 2 tm_mday(日) 1 - 31 3 tm_hour(时) 0 - 23 4 tm_min(分) 0 - 59 5 tm_sec(秒) 0 - 61 6 tm_wday(weekday) 0 - 6(0表示周日) 7 tm_yday(一年中的第几天) 1 - 366 8 tm_isdst(是否是夏令时) 默认为-1
-
time模块的方法
- time.localtime([secs]):将一个时间戳转换为当前时区的struct_time。secs参数未提供,则以当前时间为准。
- time.gmtime([secs]):和localtime()方法类似,gmtime()方法是将一个时间戳转换为UTC时区(0时区)的struct_time。
- time.time():返回当前时间的时间戳。
- time.mktime(t):将一个struct_time转化为时间戳。
- time.sleep(secs):线程推迟指定的时间运行。单位为秒。
- time.asctime([t]):把一个表示时间的元组或者struct_time表示为这种形式:'Sun Oct 1 12:04:38 2017'。如果没有参数,将会将time.localtime()作为参数传入。
- time.ctime([secs]):把一个时间戳(按秒计算的浮点数)转化为time.asctime()的形式。如果参数未给或者为None的时候,将会默认time.time()为参数。它的作用相当于time.asctime(time.localtime(secs))。
-
time.strftime(format[, t]):把一个代表时间的元组或者struct_time(如由time.localtime()和time.gmtime()返回)转化为格式化的时间字符串。如果t未指定,将传入time.localtime()。
- 举例:time.strftime("%Y-%m-%d %X", time.localtime()) #输出'2017-10-01 12:14:23'
-
time.strptime(string[, format]):把一个格式化时间字符串转化为struct_time。实际上它和strftime()是逆操作。
- 举例:time.strptime('2017-10-3 17:54',"%Y-%m-%d %H:%M") #输出 time.struct_time(tm_year=2017, tm_mon=10, tm_mday=3, tm_hour=17, tm_min=54, tm_sec=0, tm_wday=1, tm_yday=276, tm_isdst=-1)
- 在Python中,通常有这几种方式来表示时间:
-
-
字符串转时间格式对应表
1 %a Locale’s abbreviated weekday name. 2 %A Locale’s full weekday name. 3 %b Locale’s abbreviated month name. 4 %B Locale’s full month name. 5 %c Locale’s appropriate date and time representation. 6 %d Day of the month as a decimal number [01,31]. 7 %H Hour (24-hour clock) as a decimal number [00,23]. 8 %I Hour (12-hour clock) as a decimal number [01,12]. 9 %j Day of the year as a decimal number [001,366]. 10 %m Month as a decimal number [01,12]. 11 %M Minute as a decimal number [00,59]. 12 %p Locale’s equivalent of either AM or PM. (1) 13 %S Second as a decimal number [00,61]. (2) 14 %U Week number of the year (Sunday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Sunday are considered to be in week 0. (3) 15 %w Weekday as a decimal number [0(Sunday),6]. 16 %W Week number of the year (Monday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Monday are considered to be in week 0. (3) 17 %x Locale’s appropriate date representation. 18 %X Locale’s appropriate time representation. 19 %y Year without century as a decimal number [00,99]. 20 %Y Year with century as a decimal number. 21 %z Time zone offset indicating a positive or negative time difference from UTC/GMT of the form +HHMM or -HHMM, where H represents decimal hour digits and M represents decimal minute digits [-23:59, +23:59]. 22 %Z Time zone name (no characters if no time zone exists). 23 %% A literal '%' character.
-
import time #返回当前时间的时间戳 time.time() #结果为:1537339625.2724273 time.time() #结果为:1537339629.5167184 time.time() #结果为:1537339633.3674865 time.time() #结果为:1537339650.316459 time.time() #结果为:1537339651.5483134 time.time() #结果为:1537339652.9071617 time.time() #结果为:1537339654.12688 time.time() / 3600 /24 /365 #结果为:48.74872318235897 #将一个时间戳转换为当前时区的struct_time time.localtime() #结果为:time.struct_time(tm_year=2018, tm_mon=9, tm_mday=19, tm_hour=14, tm_min=50, tm_sec=32, tm_wday=2, tm_yday=262, tm_isdst=0) time.localtime() #结果为:time.struct_time(tm_year=2018, tm_mon=9, tm_mday=19, tm_hour=14, tm_min=50, tm_sec=39, tm_wday=2, tm_yday=262, tm_isdst=0) a = time.localtime() a.tm_year #结果为:2018 '%s-%s-%s'%(a.tm_year,a.tm_mon,a.tm_mday) #结果为:'2018-9-19' #和localtime()方法类似,将一个时间戳转换为UTC时区(0时区)的struct_time time.gmtime() #结果为:time.struct_time(tm_year=2018, tm_mon=9, tm_mday=19, tm_hour=7, tm_min=6, tm_sec=12, tm_wday=2, tm_yday=262, tm_isdst=0) a=time.localtime(1403232424) a #结果为:time.struct_time(tm_year=2014, tm_mon=6, tm_mday=20, tm_hour=10, tm_min=47, tm_sec=4, tm_wday=4, tm_yday=171, tm_isdst=0) a=time.localtime(140323242) a #结果为:time.struct_time(tm_year=1974, tm_mon=6, tm_mday=13, tm_hour=10, tm_min=40, tm_sec=42, tm_wday=3, tm_yday=164, tm_isdst=0) #将一个struct_time转化为时间戳 time.mktime(a) #结果为:140323242.0 #线程推迟指定的时间运行。单位为秒 time.sleep(2) #把一个表示时间的元组或者struct_time表示为这种形式:'Sun Oct 1 12:04:38 2017'。如果没有参数,将会将time.localtime()作为参数传入。 time.asctime() #结果为:'Wed Sep 19 18:12:52 2018' #把一个时间戳(按秒计算的浮点数)转化为time.asctime()的形式 time.ctime() #结果为:'Wed Sep 19 18:13:21 2018' time.ctime(123232) #结果为:'Fri Jan 2 18:13:52 1970' time.ctime(0) #结果为:'Thu Jan 1 08:00:00 1970' #把一个代表时间的元组或者struct_time 转化为格式化的时间字符串。 time.strftime('%Y-%m-%d') #结果为'2018-09-19' time.strftime('%Y-%m-%d %H:%M:%S',) #结果为'2018-09-19 18:19:16' time.strftime('%Y-%m-%d %H:%M:%S',a) #结果为'1974-06-13 13:40:42' time.strftime('%Y-%m-%d %H:%M:%S %a',a) #结果为'1974-06-13 13:40:42 Thu' time.strftime('%Y-%m-%d %H:%M:%S %A',a) #结果为'1974-06-13 13:40:42 Thursday' time.strftime('%Y-%m-%d %H:%M:%S %p',a) #结果为'1974-06-13 13:40:42 AM' time.strftime('%Y-%m-%d %H:%M:%S %U') #结果为'2018-09-19 18:20:36 37' time.strftime('%Y-%m-%d %H:%M:%S %w') #结果为'2018-09-19 18:21:02 3' time.strftime('%y-%m-%d %H:%M:%S %w') #结果为'18-09-19 18:21:29 3' time.strftime('%y-%m-%d %H:%M:%S %z') #结果为'18-09-19 18:21:41 +0800' time.strftime('%y-%m-%d %H:%M:%S %Z') #结果为'18-09-19 18:21:45 ?D1¨²¡À¨º¡Á?¨º¡À??' #把一个格式化时间字符串转化为struct_time,实际上它和strftime()是逆操作。 s=time.strftime('%Y %m-%d %H:%M:%S') s #结果为'2018 09-19 18:26:23' time.strptime(s,'%Y %m-%d %H:%M:%S') #结果为time.struct_time(tm_year=2018, tm_mon=9, tm_mday=19, tm_hour=18, tm_min=26, tm_sec=23, tm_wday=2, tm_yday=262, tm_isdst=-1) s2 = time.strptime(s,'%Y %m-%d %H:%M:%S') time.mktime(s2) #结果为1537341983.0
-
常用模块学习—tatetime 模块详解
相比于time模块,datetime模块的接口则更直观、更容易调用。
datetime模块定义了下面这几个类:
- datetime.date:表示日期的类。常用的属性有year, month, day;
- datetime.time:表示时间的类。常用的属性有hour, minute, second, microsecond;
- datetime.datetime:表示日期时间。
- datetime.timedelta:表示时间间隔,即两个时间点之间的长度。
- datetime.tzinfo:与时区有关的相关信息。(这里不详细充分讨论该类,感兴趣的童鞋可以参考python手册)
我们需要记住的方法仅以下几个:
- d=datetime.datetime.now() 返回当前的datetime日期类型
d.timestamp(),d.today(), d.year,d.timetuple()等方法可以调用
- datetime.date.fromtimestamp(322222) 把一个时间戳转为datetime日期类型
- 时间运算
>>> datetime.datetime.now() datetime.datetime(2017, 10, 1, 12, 53, 11, 821218) >>> datetime.datetime.now() + datetime.timedelta(4) #当前时间 +4天 datetime.datetime(2017, 10, 5, 12, 53, 35, 276589) >>> datetime.datetime.now() + datetime.timedelta(hours=4) #当前时间+4小时 datetime.datetime(2017, 10, 1, 16, 53, 42, 876275)
- 时间替换
>>> d.replace(year=2999,month=11,day=30)
datetime.date(2999, 11, 30)
import datetime import time datetime.datetime.now() #结果为:datetime.datetime(2018, 9, 19, 19, 9, 38, 72617) a=datetime.datetime.now() a.year #结果为:2018 a.month #结果为:9 a #结果为:datetime.datetime(2018, 9, 19, 19, 10, 30, 236846) time.time() #结果为:1537344708.7243214 datetime.date.fromtimestamp(time.time()) #结果为:datetime.date(2018, 9, 19) d2 = datetime.date.fromtimestamp(time.time()) d2.year #结果为:2018 d2.timetuple() #结果为:time.struct_time(tm_year=2018, tm_mon=9, tm_mday=19, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=262, tm_isdst=-1) #时间运算 datetime.timedelta(1) #结果为:datetime.timedelta(days=1) datetime.datetime.now() #结果为:datetime.datetime(2018, 9, 19, 19, 18, 18, 334682) t = datetime.timedelta(1) datetime.datetime.now() - t #结果为:datetime.datetime(2018, 9, 18, 19, 18, 33, 472953) datetime.datetime.now() - datetime.timedelta(days=1) #结果为:datetime.datetime(2018, 9, 18, 19, 19, 45, 149420) datetime.datetime.now() - datetime.timedelta(days=4) #结果为:datetime.datetime(2018, 9, 15, 19, 19, 57, 147533) datetime.datetime.now() - datetime.timedelta(hours=3) #结果为:datetime.datetime(2018, 9, 19, 16, 20, 17, 150411) datetime.datetime.now() + datetime.timedelta(hours=3) #结果为:datetime.datetime(2018, 9, 19, 22, 20, 29, 46632) datetime.datetime.now() + datetime.timedelta(minutes=3) #结果为:datetime.datetime(2018, 9, 19, 19, 23, 43, 578674) datetime.datetime.now() + datetime.timedelta(seconds=3) #结果为:datetime.datetime(2018, 9, 19, 19, 21, 14, 1416) #时间替换 datetime.datetime.now() #结果为:datetime.datetime(2018, 9, 19, 19, 24, 16, 789861) d = datetime.datetime.now() d.replace() #结果为:datetime.datetime(2018, 9, 19, 19, 24, 22, 384904) d.replace(year=2016) #结果为:datetime.datetime(2016, 9, 19, 19, 24, 22, 384904) d.replace(year=2016,month=8) #结果为:datetime.datetime(2016, 8, 19, 19, 24, 22, 384904) d.replace(year=2016,month=8,day=21) #结果为:datetime.datetime(2016, 8, 21, 19, 24, 22, 384904)