整型与浮点型html
#整型int 做用:年纪,等级,身份证号,qq号等整型数字相关 定义: age=10 #本质age=int(10) #浮点型float 做用:薪资,身高,体重,体质参数等浮点数相关 salary=3000.3 #本质salary=float(3000.3) #二进制,十进制,八进制,十六进制
其余数字类型(了解)python
#长整形(了解) 在python2中(python3中没有长整形的概念): >>> num=2L >>> type(num) <type 'long'> #复数(了解) >>> x=1-2j >>> x.real 1.0 >>> x.imag -2.0
#做用:名字,性别,国籍,地址等描述信息 #定义:在单引号\双引号\三引号内,由一串字符组成 name='egon' #优先掌握的操做: 按索引取值(正向取+反向取) :只能取 切片(顾头不顾尾,步长) 长度len 成员运算in和not in
移除空白strip 切分split
循环
#做用:多个装备,多个爱好,多门课程,多个女友等 #定义:[]内能够有多个任意类型的值,逗号分隔 my_girl_friends=['laoyi','laoer','laosan',4,5] #本质my_girl_friends=list([...]) 或 l=list('abc') #优先掌握的操做: 按索引存取值(正向存取+反向存取):便可存也能够取 切片(顾头不顾尾,步长) 长度 成员运算in和not in
追加 删除 循环
#ps:反向步长 l=[1,2,3,4,5,6] #正向步长 l[0:3:1] #[1, 2, 3] #反向步长 l[2::-1] #[3, 2, 1] #列表翻转 l[::-1] #[6, 5, 4, 3, 2, 1]
#做用:存多个值,对比列表来讲,元组不可变(是能够当作字典的key的),主要是用来读 #定义:与列表类型比,只不过[]换成() age=(11,22,33,44,55)本质age=tuple((11,22,33,44,55)) #优先掌握的操做: 按索引取值(正向取+反向取):只能取 切片(顾头不顾尾,步长) 长度 成员运算in和not in 循环
#做用:存多个值,key-value存取,取值速度快 #定义:key必须是不可变类型,value能够是任意类型 info={'name':'laoyi','age':18,'sex':'male'} #本质info=dict({....}) 或 info=dict(name='laoyi',age=18,sex='male') 或 info=dict([['name','laoyi'],('age',18)]) 或 {}.fromkeys(('name','age','sex'),None) #优先掌握的操做: 按key存取值:可存可取 长度len 成员运算in和not in 删除 键keys(),值values(),键值对items() 循环
#利用setdefault解决重复赋值 ''' setdefault的功能 1:key存在,则不赋值,key不存在则设置默认值 2:key存在,返回的是key对应的已有的值,key不存在,返回的则是要设置的默认值 d={} print(d.setdefault('a',1)) #返回1 d={'a':2222} print(d.setdefault('a',1)) #返回2222 ''' s='hello alex alex say hello sb sb' dic={} words=s.split() for word in words: #word='alex' dic.setdefault(word,s.count(word)) print(dic) #利用集合,去掉重复,减小循环次数 s='hello laoda laoda say hello sb sb' dic={} words=s.split() words_set=set(words) for word in words_set: dic[word]=s.count(word) print(dic)
#做用:去重,关系运算, #定义: 知识点回顾 可变类型是不可hash类型 不可变类型是可hash类型 #定义集合: 集合:能够包含多个元素,用逗号分割, 集合的元素遵循三个原则: 1:每一个元素必须是不可变类型(可hash,可做为字典的key) 2:没有重复的元素 3:无序 注意集合的目的是将不一样的值存放到一块儿,不一样的集合间用来作关系运算,无需纠结于集合中单个值 #优先掌握的操做: 长度len 成员运算in和not in |合集 &交集 -差集 ^对称差集 == >,>= ,<,<= 父集,子集
按存储空间的占用分(从低到高)程序员
数字
字符串
集合:无序,即无序存索引相关信息
元组:有序,须要存索引相关信息,不可变
列表:有序,须要存索引相关信息,可变,须要处理数据的增删改
字典:无序,须要存key与value映射的相关信息,可变,须要处理数据的增删改
按存值个数区分web
标量/原子类型 | 数字,字符串 |
容器类型 | 列表,元组,字典 |
按可变不可变区分算法
可变 | 列表,字典 |
不可变 | 数字,字符串,元组 |
按访问顺序区分shell
直接访问 | 数字 |
顺序访问(序列类型) | 字符串,列表,元组 |
key值访问(映射类型) | 字典 |
1. 什么是匿名函数?数据库
匿名就是没有名字
def func(x,y,z=1): return x+y+z 匿名 lambda x,y,z=1:x+y+z #与函数有相同的做用域,可是匿名意味着引用计数为0,使用一次就释放,除非让其有名字 func=lambda x,y,z=1:x+y+z func(1,2,3) #让其有名字就没有意义
匿名函数有个限制,就是只能有一个表达式,不用写,返回值就是该表达式的结果。
return
2. 有名字的函数与匿名函数的对比express
#有名函数与匿名函数的对比 有名函数:循环使用,保存了名字,经过名字就能够重复引用函数功能 匿名函数:一次性使用,随时随时定义 应用:max,min,sorted,map,reduce,filter
它语法简单,简化代码,不会产生命名冲突,污染命名空间。即用即抛。
#内部函数包含对外部做用域而非全局做用域的引用 #提示:以前咱们都是经过参数将外部的值传给函数,闭包提供了另一种思路 def counter(): n=0 def incr(): nonlocal n x=n n+=1 return x return incr c=counter() print(c()) print(c()) print(c()) print(c.__closure__[0].cell_contents) #查看闭包的元素
#闭包的意义:返回的函数对象,不只仅是一个函数对象,在该函数外还包裹了一层做用域,这使得,该函数不管在何处调用,优先使用本身外层包裹的做用域 #应用领域:延迟计算(原来咱们是传参,如今咱们是包起来) from urllib.request import urlopen def index(url): def get(): return urlopen(url).read() return get baidu=index('http://www.baidu.com') print(baidu().decode('utf-8'))
装饰器就是闭包函数的一种应用场景编程
#开放封闭原则:对修改封闭,对扩展开放
装饰器他人的器具,自己能够是任意可调用对象,被装饰者也能够是任意可调用对象。
强调装饰器的原则:1 不修改被装饰对象的源代码 2 不修改被装饰对象的调用方式 装饰器的目标:在遵循1和2的前提下,为被装饰对象添加上新功能
import time def timmer(func): def wrapper(*args,**kwargs): start_time=time.time() res=func(*args,**kwargs) stop_time=time.time() print('run time is %s' %(stop_time-start_time)) return res return wrapper @timmer def foo(): time.sleep(3) print('from foo') foo()
def auth(driver='file'): def auth2(func): def wrapper(*args,**kwargs): name=input("user: ") pwd=input("pwd: ") if driver == 'file': if name == 'egon' and pwd == '123': print('login successful') res=func(*args,**kwargs) return res elif driver == 'ldap': print('ldap') return wrapper return auth2 @auth(driver='file') def foo(name): print(name) foo('egon')
被装饰函数的正上方,单独一行
@deco1
@deco2
@deco3
def foo(): pass foo=deco1(deco2(deco3(foo)))
from functools import wraps def deco(func): @wraps(func) #加在最内层函数正上方 def wrapper(*args,**kwargs): return func(*args,**kwargs) return wrapper @deco def index(): '''哈哈哈哈''' print('from index') print(index.__doc__)
1 迭代的概念浏览器
#迭代是一个重复的过程,每次重复即一次迭代,而且每次迭代的结果都是下一次迭代的初始值 while True: #只是单纯地重复,于是不是迭代 print('===>') l=[1,2,3] count=0 while count < len(l): #迭代 print(l[count]) count+=1
2 为什么要有迭代器?什么是可迭代对象?什么是迭代器对象?
#一、为什么要有迭代器? 对于序列类型:字符串、列表、元组,咱们可使用索引的方式迭代取出其包含的元素。但对于字典、集合、文件等类型是没有索引的,若还想取出其内部包含的元素,则必须找出一种不依赖于索引的迭代方式,这就是迭代器 #二、什么是可迭代对象? 可迭代对象指的是内置有__iter__方法的对象,即obj.__iter__,以下 'hello'.__iter__ (1,2,3).__iter__ [1,2,3].__iter__ {'a':1}.__iter__ {'a','b'}.__iter__ open('a.txt').__iter__ #三、什么是迭代器对象? 可迭代对象执行obj.__iter__()获得的结果就是迭代器对象 而迭代器对象指的是即内置有__iter__又内置有__next__方法的对象 文件类型是迭代器对象 open('a.txt').__iter__() open('a.txt').__next__() #四、注意: 迭代器对象必定是可迭代对象,而可迭代对象不必定是迭代器对象
3 迭代器对象的使用
dic={'a':1,'b':2,'c':3} iter_dic=dic.__iter__() #获得迭代器对象,迭代器对象即有__iter__又有__next__,可是:迭代器.__iter__()获得的仍然是迭代器自己 iter_dic.__iter__() is iter_dic #True print(iter_dic.__next__()) #等同于next(iter_dic) print(iter_dic.__next__()) #等同于next(iter_dic) print(iter_dic.__next__()) #等同于next(iter_dic) # print(iter_dic.__next__()) #抛出异常StopIteration,或者说结束标志 #有了迭代器,咱们就能够不依赖索引迭代取值了 iter_dic=dic.__iter__() while 1: try: k=next(iter_dic) print(dic[k]) except StopIteration: break #这么写太丑陋了,须要咱们本身捕捉异常,控制next,python这么牛逼,能不能帮我解决呢?能,请看for循环
4 for循环
#基于for循环,咱们能够彻底再也不依赖索引去取值了 dic={'a':1,'b':2,'c':3} for k in dic: print(dic[k]) #for循环的工做原理 #1:执行in后对象的dic.__iter__()方法,获得一个迭代器对象iter_dic #2: 执行next(iter_dic),将获得的值赋值给k,而后执行循环体代码 #3: 重复过程2,直到捕捉到异常StopIteration,结束循环
5 迭代器的优缺点
#优势: - 提供一种统一的、不依赖于索引的迭代方式 - 惰性计算,节省内存 #缺点: - 没法获取长度(只有在next完毕才知道到底有几个值) - 一次性的,只能日后走,不能往前退
1 什么是生成器
#只要函数内部包含有yield关键字,那么函数名()的到的结果就是生成器,而且不会执行函数内部代码 def func(): print('====>first') yield 1 print('====>second') yield 2 print('====>third') yield 3 print('====>end') g=func() print(g) #<generator object func at 0x0000000002184360>
2 生成器就是迭代器
g.__iter__ g.__next__ #二、因此生成器就是迭代器,所以能够这么取值 res=next(g) print(res)
3 生成器表达式
#一、把列表推导式的[]换成()就是生成器表达式 #二、示例:生一筐鸡蛋变成给你一只老母鸡,用的时候就下蛋,这也是生成器的特性 >>> chicken=('鸡蛋%s' %i for i in range(5)) >>> chicken <generator object <genexpr> at 0x10143f200> >>> next(chicken) '鸡蛋0' >>> list(chicken) #因chicken可迭代,于是能够转成列表 ['鸡蛋1', '鸡蛋2', '鸡蛋3', '鸡蛋4',] #三、优势:省内存,一次只产生一个值在内存中
内置函数 参考:https://docs.python.org/3/library/functions.html?highlight=built#ascii
高阶函数
sorted
排序算法
排序也是在程序中常常用到的算法。不管使用冒泡排序仍是快速排序,排序的核心是比较两个元素的大小。
若是是数字,咱们能够直接比较,但若是是字符串或者两个dict呢?直接比较数学上的大小是没有意义的,所以,比较的过程必须经过函数抽象出来。
一般规定,对于两个元素x和y,若是认为x < y,则返回-1,若是认为x == y,则返回0,若是认为x > y,则返回1,这样,排序算法就不用关心具体的比较过程,而是根据比较结果直接排序。 Python内置的sorted()函数就能够对list进行排序: >>> sorted([36, 5, 12, 9, 21]) [5, 9, 12, 21, 36] 此外,sorted()函数也是一个高阶函数,它还能够接收一个比较函数来实现自定义的排序。好比,若是要倒序排序,咱们就能够自定义一个reversed_cmp函数: def reversed_cmp(x, y): if x > y: return -1 if x < y: return 1 return 0 传入自定义的比较函数reversed_cmp,就能够实现倒序排序: >>> sorted([36, 5, 12, 9, 21], reversed_cmp) [36, 21, 12, 9, 5] 咱们再看一个字符串排序的例子: >>> sorted(['bob', 'about', 'Zoo', 'Credit']) ['Credit', 'Zoo', 'about', 'bob'] 默认状况下,对字符串排序,是按照ASCII的大小比较的,因为'Z' < 'a',结果,大写字母Z会排在小写字母a的前面。 如今,咱们提出排序应该忽略大小写,按照字母序排序。要实现这个算法,没必要对现有代码大加改动,只要咱们能定义出忽略大小写的比较算法就能够: def cmp_ignore_case(s1, s2): u1 = s1.upper() u2 = s2.upper() if u1 < u2: return -1 if u1 > u2: return 1 return 0 忽略大小写来比较两个字符串,实际上就是先把字符串都变成大写(或者都变成小写),再比较。 这样,咱们给sorted传入上述比较函数,便可实现忽略大小写的排序: >>> sorted(['bob', 'about', 'Zoo', 'Credit'], cmp_ignore_case) ['about', 'bob', 'Credit', 'Zoo'] 从上述例子能够看出,高阶函数的抽象能力是很是强大的,并且,核心代码能够保持得很是简洁。
map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次做用到序列的每一个元素,并把结果做为新的Iterator返回。 举例说明,好比咱们有一个函数f(x)=x2,要把这个函数做用在一个list [1, 2, 3, 4, 5, 6, 7, 8, 9]上,就能够用map()实现以下: 如今,咱们用Python代码实现: >>> def f(x): ... return x * x ... >>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9]) >>> list(r) [1, 4, 9, 16, 25, 36, 49, 64, 81] map()传入的第一个参数是f,即函数对象自己。因为结果r是一个Iterator,Iterator是惰性序列,所以经过list()函数让它把整个序列都计算出来并返回一个list。 L = [] for n in [1, 2, 3, 4, 5, 6, 7, 8, 9]: L.append(f(n)) print(L) map()做为高阶函数,事实上它把运算规则抽象了,所以,咱们不但能够计算简单的f(x)=x2,还能够计算任意复杂的函数,好比,把这个list全部数字转为字符串: >>> list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9])) ['1', '2', '3', '4', '5', '6', '7', '8', '9'] 再看reduce的用法。reduce把一个函数做用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素作累积计算,其效果就是: reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4) 比方说对一个序列求和,就能够用reduce实现: >>> from functools import reduce >>> def add(x, y): ... return x + y ... >>> reduce(add, [1, 3, 5, 7, 9]) 25 固然求和运算能够直接用Python内建函数sum(),不必动用reduce。 可是若是要把序列[1, 3, 5, 7, 9]变换成整数13579,reduce就能够派上用场: >>> from functools import reduce >>> def fn(x, y): ... return x * 10 + y ... >>> reduce(fn, [1, 3, 5, 7, 9]) 13579 这个例子自己没多大用处,可是,若是考虑到字符串str也是一个序列,对上面的例子稍加改动,配合map(),咱们就能够写出把str转换为int的函数: >>> from functools import reduce >>> def fn(x, y): ... return x * 10 + y ... >>> def char2num(s): ... return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s] ... >>> reduce(fn, map(char2num, '13579')) 13579 整理成一个str2int的函数就是: from functools import reduce def str2int(s): def fn(x, y): return x * 10 + y def char2num(s): return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s] return reduce(fn, map(char2num, s)) 还能够用lambda函数进一步简化成: from functools import reduce def char2num(s): return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s] def str2int(s): return reduce(lambda x, y: x * 10 + y, map(char2num, s)) 也就是说,假设Python没有提供int()函数,你彻底能够本身写一个把字符串转化为整数的函数,并且只须要几行代码!
二 列表推导式
#一、示例 egg_list=[] for i in range(10): egg_list.append('鸡蛋%s' %i) egg_list=['鸡蛋%s' %i for i in range(10)] #二、语法 [expression for item1 in iterable1 if condition1 for item2 in iterable2 if condition2 ... for itemN in iterableN if conditionN ] 相似于 res=[] for item1 in iterable1: if condition1: for item2 in iterable2: if condition2 ... for itemN in iterableN: if conditionN: res.append(expression) #三、优势:方便,改变了编程习惯,可称之为声明式编程
其一, 在不加括号时候, and优先级大于or
其二, x or y 的值只多是x或y. x为真就是x, x为假就是y
第三, x and y 的值只多是x或y. x为真就是y, x为假就是x
显然,对于, 1 or 5 and 4: 先算5 and 4, 5为真, 值为4. 再算1 or 4, 1 为真,值为1
对于, (1 or 5) and 4: 先算1 or 5, 1为真, 值为1. 再算1 and 4, 1为真,值为4
求值技巧
关于求值的顺序,先左部,再右部,还要加入“短路”机制,说明这点的文档原文:
对应同一优先级,我我的的理解为:or的目的是找到做用范围内第一个True或最后一个False,and的目的是找到做用范围第一个False或最后一个True。(其中,做用范围内的概念必须明确)。
#对于and而言,第一行返回(做用范围内)第一个假值,第二行返回最后一个正值
#对于or而言,第一行返回(做用范围内)第一个真值,第二行返回最后一个假值
这个说实话,我三言两语无法说清,因此我只能po上老师的博客了:
http://www.cnblogs.com/linhaifeng/articles/6817679.html
GIL锁
GIL锁并非PYTHON的特性,是在实现cpython解释器的时候引入的一个概念,
python彻底能够不依赖GIL
一个防止 多线程并发执行机器码的一个互斥锁
为何会有GIL锁
因为物理上的限制,cpu厂商在核心频率上的比赛被多核取代,为了更有效的利用多喝处理器的性能,
就出现了多线程的编程方式,随之带来的问题就是线程间数据一致性和状态同步的困难
即便在cpu内部的缓存也不例外,
python固然也逃不开,为了利用多核,python开始支持多线程。而解决多线程之间数据完整性和状态同步的最简单方法就是枷锁。
因此就有了GIL这把超级大锁,而当愈来愈多代码库开发者,接收了这种设定以后,开始大量依赖这样特性(即默认线程安全)
但是慢慢的这种方式被发现是蛋疼并且低效的,当你们视图去拆分和去除GIL的时候,发现大量库的开发组已经中毒依赖GIL并且很难去除了
总结:
由于GIL的存在,只有IO密集型的场景下,多线程会获得较好的性能
若是对计算性能较高的程序能够考虑把核心部分换成或者用其余语言实现
os就是一个普通的python库,用来向Python程序提供运行环境,特别是在文件系统、建立新进程、获取操做系统自己的一些信息(好比uname),并屏蔽各类不一样操做系统之间的细节差别。 sys模块则是python程序用来请求解释器行为的接口。
好比关于调试类的(trace, frames,except)等,profiling类(stats, getsizeof),运行时环境类(python path, stderr, stdout),解释器自己(如version)
。inspect某种程度上能够当作是在sys提供的功能上的一个包装。
os.getcwd() 获取当前工做目录,即当前python脚本工做的目录路径 os.chdir("dirname") 改变当前脚本工做目录;至关于shell下cd os.curdir 返回当前目录: ('.') os.pardir 获取当前目录的父目录字符串名:('..') os.makedirs('dirname1/dirname2') 可生成多层递归目录 os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 os.mkdir('dirname') 生成单级目录;至关于shell中mkdir dirname os.rmdir('dirname') 删除单级空目录,若目录不为空则没法删除,报错;至关于shell中rmdir dirname os.listdir('dirname') 列出指定目录下的全部文件和子目录,包括隐藏文件,并以列表方式打印 os.remove() 删除一个文件 os.rename("oldname","newname") 重命名文件/目录 os.stat('path/filename') 获取文件/目录信息 os.sep 输出操做系统特定的路径分隔符,win下为"\\",Linux下为"/" os.linesep 输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n" os.pathsep 输出用于分割文件路径的字符串 win下为;,Linux下为: os.name 输出字符串指示当前使用平台。win->'nt'; Linux->'posix' os.system("bash command") 运行shell命令,直接显示 os.environ 获取系统环境变量 os.path.abspath(path) 返回path规范化的绝对路径 os.path.split(path) 将path分割成目录和文件名二元组返回 os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素 os.path.basename(path) 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素 os.path.exists(path) 若是path存在,返回True;若是path不存在,返回False os.path.isabs(path) 若是path是绝对路径,返回True os.path.isfile(path) 若是path是一个存在的文件,返回True。不然返回False os.path.isdir(path) 若是path是一个存在的目录,则返回True。不然返回False os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径以前的参数将被忽略 os.path.getatime(path) 返回path所指向的文件或者目录的最后存取时间 os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间 os.path.getsize(path) 返回path的大小
os路径处理 import os #具体应用 import os,sys possible_topdir = os.path.normpath(os.path.join( os.path.abspath(__file__), os.pardir, #上一级 os.pardir, os.pardir )) sys.path.insert(0,possible_topdir)
sys.argv 命令行参数List,第一个元素是程序自己路径
sys.exit(n) 退出程序,正常退出时exit(0)
sys.version 获取Python解释程序的版本信息
sys.maxint 最大的Int值
sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform 返回操做系统平台名称
在Python中,一般有这几种方式来表示时间:
时间戳(timestamp):一般来讲,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。咱们运行“type(time.time())”,返回的是float类型。
格式化的时间字符串(Format String)
结构化的时间(struct_time):struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天,夏令时)
import time #--------------------------咱们先以当前时间为准,让你们快速认识三种形式的时间 print(time.time()) # 时间戳:1487130156.419527 print(time.strftime("%Y-%m-%d %X")) #格式化的时间字符串:'2017-02-15 11:40:53' print(time.localtime()) #本地时区的struct_time print(time.gmtime()) #UTC时区的struct_time 结构化时间
计算机认识的时间只能是'时间戳'格式,而程序员可处理的或者说人类能看懂的时间有: '格式化的时间字符串','结构化的时间' ,因而有了下图的转换关系
#--------------------------按图1转换时间 # localtime([secs]) # 将一个时间戳转换为当前时区的struct_time。secs参数未提供,则以当前时间为准。 time.localtime() time.localtime(1473525444.037215) # gmtime([secs]) 和localtime()方法相似,gmtime()方法是将一个时间戳转换为UTC时区(0时区)的struct_time。 # mktime(t) : 将一个struct_time转化为时间戳。 print(time.mktime(time.localtime()))#1473525749.0 # strftime(format[, t]) : 把一个表明时间的元组或者struct_time(如由time.localtime()和 # time.gmtime()返回)转化为格式化的时间字符串。若是t未指定,将传入time.localtime()。若是元组中任何一个 # 元素越界,ValueError的错误将会被抛出。 print(time.strftime("%Y-%m-%d %X", time.localtime()))#2016-09-11 00:49:56 # time.strptime(string[, format]) # 把一个格式化时间字符串转化为struct_time。实际上它和strftime()是逆操做。 print(time.strptime('2011-05-05 16:37:06', '%Y-%m-%d %X')) #time.struct_time(tm_year=2011, tm_mon=5, tm_mday=5, tm_hour=16, tm_min=37, tm_sec=6, # tm_wday=3, tm_yday=125, tm_isdst=-1) #在这个函数中,format默认为:"%a %b %d %H:%M:%S %Y"。
1 #--------------------------按图2转换时间 2 # asctime([t]) : 把一个表示时间的元组或者struct_time表示为这种形式:'Sun Jun 20 23:21:05 1993'。 3 # 若是没有参数,将会将time.localtime()做为参数传入。 4 print(time.asctime())#Sun Sep 11 00:43:43 2016 5 6 # ctime([secs]) : 把一个时间戳(按秒计算的浮点数)转化为time.asctime()的形式。若是参数未给或者为 7 # None的时候,将会默认time.time()为参数。它的做用至关于time.asctime(time.localtime(secs))。 8 print(time.ctime()) # Sun Sep 11 00:46:38 2016 9 print(time.ctime(time.time())) # Sun Sep 11 00:46:38 2016
1 #--------------------------其余用法 2 # sleep(secs) 3 # 线程推迟指定的时间运行,单位为秒。
datetime
#时间加减 import datetime # print(datetime.datetime.now()) #返回 2016-08-19 12:47:03.941925 #print(datetime.date.fromtimestamp(time.time()) ) # 时间戳直接转成日期格式 2016-08-19 # print(datetime.datetime.now() ) # print(datetime.datetime.now() + datetime.timedelta(3)) #当前时间+3天 # print(datetime.datetime.now() + datetime.timedelta(-3)) #当前时间-3天 # print(datetime.datetime.now() + datetime.timedelta(hours=3)) #当前时间+3小时 # print(datetime.datetime.now() + datetime.timedelta(minutes=30)) #当前时间+30分 # # c_time = datetime.datetime.now() # print(c_time.replace(minute=3,hour=2)) #时间替换
类中最经常使用到的方法是
即,实例对象做为第一个参数传递给函数
例如,下面是一个基本的实例方法
class Kls(object): def __init__(self, data): self.data = data def printd(self): print(self.data) ik1 = Kls('arun') ik2 = Kls('seema') ik1.printd() ik2.printd()
获得的输出:
调用关系图:
1/2 参数传递给函数 3 self参数指向实例自己 4 咱们不须要显式提供实例,解释器自己会处理
假如咱们想仅实现类之间交互而不是经过实例?咱们能够在类以外创建一个简单的函数来实现这个功能,可是将会使代码扩散到类以外,这个可能对将来代码维护带来问题。
例如:
def get_no_of_instances(cls_obj): return cls_obj.no_inst class Kls(object): no_inst = 0 def __init__(self): Kls.no_inst = Kls.no_inst + 1 ik1 = Kls() ik2 = Kls() print(get_no_of_instances(Kls))
2
如今咱们要作的是在类里建立一个函数,这个函数参数是类对象而不是实例对象.
在上面那个实现中,若是要实现不获取实例,须要修改以下:
def iget_no_of_instance(ins_obj): return ins_obj.__class__.no_inst class Kls(object): no_inst = 0 def __init__(self): Kls.no_inst = Kls.no_inst + 1 ik1 = Kls() ik2 = Kls() print iget_no_of_instance(ik1) 结果 2
可使用Python2.2引入的新特性,使用@classmethod在类代码中建立一个函数
class Kls(object): no_inst = 0 def __init__(self): Kls.no_inst = Kls.no_inst + 1 @classmethod def get_no_of_instance(cls_obj): return cls_obj.no_inst ik1 = Kls() ik2 = Kls() print ik1.get_no_of_instance() print Kls.get_no_of_instance()
2
2
一般,有不少状况下一些函数与类相关,但不须要任何类或实例变量就能够实现一些功能.
好比设置环境变量,修改另外一个类的属性等等.这种状况下,咱们也可使用一个函数,同样会将代码扩散到类以外(难以维护)
下面是一个例子:
IND = 'ON' def checkind(): return (IND == 'ON') class Kls(object): def __init__(self,data): self.data = data def do_reset(self): if checkind(): print('Reset done for:', self.data) def set_db(self): if checkind(): self.db = 'new db connection' print('DB connection made for:',self.data) ik1 = Kls(12) ik1.do_reset() ik1.set_db()
如今咱们使用@staticmethod, 咱们能够将全部代码放到类中
IND = 'ON' class Kls(object): def __init__(self, data): self.data = data @staticmethod def checkind(): return (IND == 'ON') def do_reset(self): if self.checkind(): print('Reset done for:', self.data) def set_db(self): if self.checkind(): self.db = 'New db connection' print('DB connection made for: ', self.data) ik1 = Kls(12) ik1.do_reset() ik1.set_db()
class Kls(object): def __init__(self, data): self.data = data def printd(self): print(self.data) @staticmethod def smethod(*arg): print('Static:', arg) @classmethod def cmethod(*arg): print('Class:', arg)
调用
>>> ik = Kls(23) >>> ik.printd() 23 >>> ik.smethod() Static: () >>> ik.cmethod() Class: (,) >>> Kls.printd() TypeError: unbound method printd() must be called with Kls instance as first argument (got nothing instead) >>> Kls.smethod() Static: () >>> Kls.cmethod() Class: (,)
1. 因为HTTP协议是无状态的协议,因此服务端须要记录用户的状态时,就须要用某种机制来识具体的用户。这个机制就是Session.典型的场景好比购物车,当你点击下单按钮时,因为HTTP协议无状态,因此并不知道是哪一个用户操做的,因此服务端要为特定的用户建立了特定的Session,用用于标识这个用户,而且跟踪用户。这样才知道购物车里面有几本书。这个Session是保存在服务端的,有一个惟一标识。 在服务端保存Session的方法不少,内存、数据库、文件都有。集群的时候也要考虑Session的转移,在大型的网站,通常会有专门的Session服务器集群,用来保存用户会话,这个时候 Session 信息都是放在内存的,使用一些缓存服务好比Memcached之类的来放 Session。2. 思考一下服务端如何识别特定的客户?这个时候Cookie就登场了。每次HTTP请求的时候,客户端都会发送相应的Cookie信息到服务端。实际上大多数的应用都是用 Cookie 来实现Session跟踪的,第一次建立Session的时候,服务端会在HTTP协议中告诉客户端,须要在 Cookie 里面记录一个Session ID,之后每次请求把这个会话ID发送到服务器,我就知道你是谁了。有人问,若是客户端的浏览器禁用了 Cookie 怎么办?通常这种状况下,会使用一种叫作URL重写的技术来进行会话跟踪,即每次HTTP交互,URL后面都会被附加上一个诸如 sid=xxxxx 这样的参数,服务端据此来识别用户。3. Cookie其实还能够用在一些方便用户的场景下,设想你某次登录过一个网站,下次登陆的时候不想再次输入帐号了,怎么办?这个信息能够写到Cookie里面,访问网站的时候,网站页面的脚本能够读取这个信息,就自动帮你把用户名给填了,可以方便一下用户。这也是Cookie名称的由来,给用户的一点甜头。因此,总结一下:Session是在服务端保存的一个数据结构,用来跟踪用户的状态,这个数据能够保存在集群、数据库、文件中;Cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息,也是实现Session的一种方式。