家里有在这个IT圈子里面,也想让我接触这个圈子,而后给我建议学的Python,
而后本身经过百度和向有学过Python的同窗了解了Python,Python这门语言,入门比较简单,
它简单易学,生态圈比较强大,涉及的地方比较多,特别是在人工智能,和数据分析这方面。
在将来我以为是往自动化,人工智能这方面发展的,因此学习了Python
balabala.....
刚开始接触Python的时候,到网上里面跟着视频学基础,
再后来网上到看技术贴,而后看到有人推荐廖雪峰的Python教程,
练项目到GitHub上面找一些小项目学习
balabala....
Python VS java
python
动态强类型,定义无需声明类型,崇尚鸭子类型
java
静态强类型,定义必需要声明定义类型
Python VS PHP
PHP 弱类型 面向web
Python 强类型 面向对象
Python VS C
Python 压倒性的代码简洁程度,缩进的使用。
C 大量的修饰词以及括号,代码量庞大
简易 :代码简单,易懂,易学
开源 可移植性强大
便于移植 :无需再次编译
编程方式多样 :函数编程,面向对象编程都支持 可扩展性和可嵌入性强大 丰富的库
动态类型 : 鸭子类型所以更加方便类型选择
运行速度比较C较弱
不能加密 : 开源性限制
构架选择太多: 没有官方框架
GIL : 全局解释器锁致使没有多线程
解释型:就是边解释边执行
执行速度快、效率高;依赖编译器、跨平台性差些。如C、C++、Delphi、Pascal,Fortran
编译型:编译后再执行
执行速度慢、效率低;依赖解释器、跨平台性好。如Tcl、Perl、Ruby、VBScript、 JavaScript
CPython 官方版本的解释器:CPython。C语言 ,命令行下运行python就是启动CPython解释器。 CPython是使用最广的Python解释器。教程的全部代码也都在CPython下执行。 IPython IPython是基于CPython之上的一个交互式解释器,
IPython只是在交互方式上有所加强,可是执行Python代码的功能和CPython是彻底同样的。
标识:
CPython用>>>做为提示符,而IPython用In [序号]:做为提示符。
PyPy
由Python写的解释器,执行速度最快。
PyPy采用JIT技术,对Python代码进行动态编译(注意不是解释),
绝大部分Python代码均可以在PyPy下运行,可是PyPy和CPython有一些是不一样的,这就致使相同的Python代码在两种解释器下执行可能会有不一样的结果。
Jython
Jython是运行在Java平台上的Python解释器,能够直接把Python代码编译成Java字节码执行。
IronPython
IronPython和Jython相似,只不过IronPython是运行在.Net平台上的Python解释器,能够直接把Python代码编译成.Net的字节码。
取舍:
使用最普遍的仍是CPython。若是要和Java或.Net平台交互,最好的办法不是用Jython或IronPython,而是经过网络调用来交互,确保各程序之间的独立性。
1字节 = 8 位
位(bit),数据存储是以“字节”(Byte)为单位,数据传输是以大可能是以“位”(bit,又名“比特”)为单位,
一个位就表明一个0或1(即一个二进制),二进制是构成存储器的最小单位,每8个位(bit,简写为b)组成一个字节(Byte,简写为B),
字节是最小一级的信息单位
b --->位(bit) B --->字节 一个字节等于8位 1B = 8 bit 1kb = 1024 B 1 MB = 1024 KB 1 GB = 1024 MB
1、使用4个空格而不是tab键进行缩进。 2、每行长度不能超过79 3、使用空行来间隔函数和类,以及函数内部的大块代码 4、必要时候,在每一行下写注释 5、使用文档注释,写出函数注释 6、在操做符和逗号以后使用空格,可是不要在括号内部使用 7、命名类和函数的时候使用一致的方式,好比使用CamelCase来命名类, 使用lower_case_with_underscores来命名函数和方法 8、在类中老是使用self来做为默认 9、尽可能不要使用魔法方法 十、默认使用UTF-8,甚至ASCII做为编码方式 11、换行可使用反斜杠,最好使用圆括号。 12、不要在一句import中多个库,
空格的使用 1. 各类右括号前不要加空格。 2. 逗号、冒号、分号前不要加空格。 3. 函数的左括号前不要加空格。如Func(1) 4. 序列的左括号前不要加空格。如list[2] 5. 操做符左右各加一个空格,不要为了对齐增长空格 6. 函数默认参数使用的赋值符左右省略空格 7. 不要将多句语句写在同一行,尽管使用‘;’容许
if/for/while语句中,即便执行语句只有一句,也必须另起一行 函数命名使用所有小写的方式,常量命名使用大写,类属性(方法和变量)使用小写 类的命名首字母大写
# 二进制转换成十进制-->int v = "0b1111011" b = int(v,2) print(b) # 123 # 十进制转换成二进制--->bin v2 = 18 print(bin(int(v2))) # 0b10010 # 八进制转换成十进制 v3 = "011" print(int(v3)) # 11 # 十进制转换成八进制:---> oct v4 = 30 print(oct(int(v4))) # 0o36 # 十六进制转换成十进制: v5 = "0x12" print(int(v5,16)) # 18 # 十进制转换成十六进制:---> hex v6 = 87 print(hex(int(v6))) # 0x57
""" 请编写一个函数实现将IP地址转换成一个整数。 如 10.3.9.12 转换规则为: 10 00001010 3 00000011 9 00001001 12 00001100 再将以上二进制拼接起来计算十进制结果:00001010 00000011 00001001 00001100 = ? """ def v1(addr): # 取每一个数 id = [int(x) for x in addr.split(".")] print(id) return sum(id[i] << [24, 16, 8, 0][i] for i in range(4)) print(v1("127.0.0.1")) # [127, 0, 0, 1] # 2130706433
998
视状况而定,机器性能好的话也能够超出此上限
1. 求结果:1 or 3 print(1 or 3) # 1 2. 求结果:1 and 3 print(1 and 3) # 3 3. 求结果:0 and 2 and 1 print(0 and 2 and 1) # 0 4. 求结果:0 and 2 or 1 print(0 and 2 or 1) # 1 5. 求结果:0 and 2 or 1 or 4 print(0 and 2 or 1 or 4) # 1 6. 求结果:0 or Flase and 1 print(0 or False and 1) # Flase 总结: # x or y 若是 x为真,则值为x, 不然为y # x and y 若是 x 为真,则值为 y,不然为 x
v1 = 1 or 3 -- 1 v2 = 1 and 3 -- 3 v3 = 0 and 2 and 1 -- 0 v4 = 0 and 2 or 1 -- 1 v5 = 0 and 2 or 1 or 4 -- 1 v6 = 0 or Flase and 1 -- False and:先后为真才为真 or:有一为真就为真 优先级:()>not>and>or 同等优先级下,从左向右
print(2 & 5) # 10 & 101 => 000 => 0
print(2 ^ 5) # 10 ^ 101 => 111 => 1*2**0+1*2**1+1*2**2=1+2+4=7
python2 默认 ascii
python3 默认 utf-8
ascii 最多只能用8位来表示(一个字节),即:2**8 = 256,因此,ASCII码最多只能表示 256 个符号。 unicode 万国码,任何一个字符==两个字节 utf-8 万国码的升级版 一个中文字符==三个字节 英文是一个字节 欧洲的是 2个字节 gbk 国内版本 一个中文字符==2个字节 英文是一个字节
gbk 转 utf-8 需经过媒介 unicode
什么是机器码 机器码(machine code),学名机器语言指令,有时也被称为原生码(Native Code),是电脑的CPU可直接解读的数据。 一般意义上来理解的话,机器码就是计算机能够直接执行,而且执行速度最快的代码。 总结:机器码是电脑CPU直接读取运行的机器指令,运行速度最快,可是很是晦涩难懂,也比较难编写 什么是字节码 字节码(Bytecode)是一种包含执行程序、由一序列 op 代码/数据对 组成的二进制文件。 字节码是一种中间码,它比机器码更抽象,须要直译器转译后才能成为机器码的中间代码。 总结:字节码是一种中间状态(中间码)的二进制代码(文件)。须要直译器转译后才能成为机器码。
#一、以字母,数字,下划线任由结合 #二、不能以命名太长,不使用拼音,中文 #三、不能以数字开头 #四、不能用关键词
#is 比较的是内存地址 #== 比较的是值
is 比较的是两个实例对象是否是彻底相同,它们是否是同一个对象,占用的内存地址是否相同。 == 比较的是两个对象的内容是否相等,即内存地址能够不同,内容同样就能够了。默认会调用对象的 __eq__()方法。
# 应用场景:简化if语句 # 格式 # 结果+ if + 条件 + else + 结果 result='gt' if 1>3 else 'lt' print(result) # lt # 理解:若是条件为真,把if前面的值赋值给变量,不然把else后面的值赋值给变量。 lambda 表达式 temp = lambda x,y:x+y print(temp(4,10)) # 14 可替代: def foo(x,y): return x+y print(foo(4,10)) # 14
1:打印时,py2须要能够不须要加括号,py3 须要 python 2 :print ('lili') , print 'lili' python 3 : print ('lili') python3 必须加括号 exec语句被python3废弃,统一使用exec函数 2:内涵 Python2:1,臃肿,源码的重复量不少。 2,语法不清晰,掺杂着C,php,Java,的一些陋习。 Python3:几乎是重构后的源码,规范,清晰,优美。 3、输出中文的区别 python2:要输出中文 需加 # -*- encoding:utf-8 -*- Python3 : 直接搞 4:input不一样 python2 :raw_input python3 :input 统一使用input函数 5:指定字节 python2在编译安装时,能够经过参数-----enable-unicode=ucs2 或-----enable-unicode=ucs4分别用于指定使用2个字节、4个字节表示一个unicode; python3没法进行选择,默认使用 ucs4 查看当前python中表示unicode字符串时占用的空间: impor sys print(sys.maxunicode) #若是值是65535,则表示使用usc2标准,即:2个字节表示 #若是值是1114111,则表示使用usc4标准,即:4个字节表示 6: py2:xrange range py3:range 统一使用range,Python3中range的机制也进行修改并提升了大数据集生成效率 7:在包的知识点里 包:一群模块文件的集合 + __init__ 区别:py2 : 必须有__init__ py3:不是必须的了 8:不相等操做符"<>"被Python3废弃,统一使用"!=" 9:long整数类型被Python3废弃,统一使用int 10:迭代器iterator的next()函数被Python3废弃,统一使用next(iterator) 11:异常StandardError 被Python3废弃,统一使用Exception 12:字典变量的has_key函数被Python废弃,统一使用in关键词 13:file函数被Python3废弃,统一使用open来处理文件,能够经过io.IOBase检查文件类型
a = 1 b = 2 a, b = b, a
0,“”,{},[],(),set()
0 False 负数 不成立的表达式 None 等
字符串用单引号(')或双引号(")括起来,不可变
1,find经过元素找索引,可切片,找不到返回-1 2,index,找不到报错。 3,split 由字符串分割成列表,默认按空格。 4,captalize 首字母大写,其余字母小写。 5,upper 全大写。 6,lower 全小写。 7,title,每一个单词的首字母大写。 8,startswith 判断以什么为开头,能够切片,总体概念。 9,endswith 判断以什么为结尾,能够切片,总体概念。 10,format格式化输出 #format的三种玩法 格式化输出 res='{} {} {}'.format('egon',18,'male') ==> egon 18 male res='{1} {0} {1}'.format('egon',18,'male') ==> 18 egon 18 res='{name} {age} {sex}'.format(sex='male',name='egon',age=18) 11,strip 默认去掉两侧空格,有条件, 12,lstrip,rstrip 14,center 居中,默认空格。 15,count查找元素的个数,能够切片,若没有返回0 16,expandtabs 将一个tab键变成8个空格,若是tab前面的字符长度不足8个,则补全8个, 17,replace(old,new,次数) 18,isdigit 字符串由字母或数字组成 isalpha, 字符串只由字母组成 isalnum 字符串只由数字组成 19,swapcase 大小写翻转 20,for i in 可迭代对象。
key: 输出全部的键 clear:清空 dic:删除的键若是没有则报错 pop:键值对删,有返回,没有原来的键会报错(自行设置返回键就不会报错) popitem:随机删键值对 del:删除的键若是没有则报错
update :更新数据 get: 不报错的查询 # 没有能够返回设定的返回值
append:在后面添加。 Insert:按照索引添加, expend:迭代着添加。 pop 删除并做为返回值 remove 按照元素去删 clear 清空列表 del 删除列表 list.count(obj) - 统计某个元素在列表中出现的次数 list.index(obj) - 从列表中找出某个值第一个匹配项的索引位置 list.reverse() - 反向列表中元素 list.sort([func]) - 对原列表进行排序
1、cmp(tuple1, tuple2):比较两个元组元素。 2、len(tuple):计算元组元素个数。 3、max(tuple):返回元组中元素最大值。 4、min(tuple):返回元组中元素最小值。 5、tuple(seq):将列表转换为元组。
set:建立集合 add: 添加元素 update:更新元素 clear:清空 pop:随机删除并返回 remove:指定删除 del: 删除集合
匿名函数:为了解决那些功能很简单的需求而设计的一句话函数 函数名 = lambda 参数 :返回值 #参数能够有多个,用逗号隔开 #匿名函数无论逻辑多复杂,只能写一行,且逻辑执行结束后的内容就是返回值 #返回值和正常的函数同样能够是任意数据类型 lambda 表达式 temp = lambda x,y:x+y print(temp(4,10)) # 14 可替代: def foo(x,y): return x+y print(foo(4,10)) # 14
pass是空语句,是为了保持程序结构的完整性。pass 不作任何事情,通常用作占位语句。
# 他们是一种动态传参,通常不肯定须要传入几个参数时,可使用其定义参数,而后从中取参 '*args':按照位置传参,将传入参数打包成一个‘元组’(打印参数为元组-- tuple) '**kwargs':按照关键字传参,将传入参数打包成一个‘字典’(打印参数为字典-- dict)
浅拷贝只是增长了一个指针指向一个存在的地址,
数据半共享(复制其数据独立内存存放,可是只拷贝成功第一层)
深拷贝是增长一个指针而且开辟了新的内存,这个增长的指针指向这个新的内存
数据彻底不共享(复制其数据完彻底全放独立的一个内存,彻底拷贝,数据不共享)
采用浅拷贝的状况,释放内存,会释放同一内存,深拷贝就不会出现释放同一内存的错误
字典套字典、列表套字典、字典套列表,列表套列表,以及各类复杂数据结构的嵌套中,会出现拷贝后的数据发生变化致使源数据发生变化
import copy # 浅拷贝 l1 = [1,2,3,[11,22,33]] l2 = l1.copy() print(l2) #[1,2,3,[11,22,33]] l2[3][2]='aaa' print(l1) #[1, 2, 3, [11, 22, 'aaa']] print(l2) #[1, 2, 3, [11, 22, 'aaa']] l1[0]= 0 print(l1) #[0, 2, 3, [11, 22, 'aaa']] print(l2) #[1, 2, 3, [11, 22, 'aaa']] print(id(l1)==id(l2)) #False # 深拷贝 import copy l1 = [1, 2, 3, [11, 22, 33]] l2 = copy.deepcopy(l1) print(l1,'>>>',l2) # [1, 2, 3, [11, 22, 33]] >>> [1, 2, 3, [11, 22, 33]] l2[3][0] = 1111 print(l1,">>>",l2) # [1, 2, 3, [11, 22, 33]] >>> [1, 2, 3, [1111, 22, 33]]
# Python垃圾回收机制 Python垃圾回收机制,主要使用'引用计数'来跟踪和回收垃圾。 在'引用计数'的基础上,经过'标记-清除'(mark and sweep)解决容器对象可能产生的循环引用问题. 经过'分代回收'以空间换时间的方法提升垃圾回收效率。 '引用计数' PyObject是每一个对象必有的内容,其中ob_refcnt就是作为引用计数。 当一个对象有新的引用时,它的ob_refcnt就会增长,当引用它的对象被删除, 它的ob_refcnt就会减小.引用计数为0时,该对象生命就结束了。 \优势:1.简单 2.实时性 \缺点:1.维护引用计数消耗资源 2.循环引用 '标记-清楚机制' 基本思路是先按需分配,等到没有空闲内存的时候从寄存器和程序栈上的引用出发, 遍历以对象为节点、以引用为边构成的图,把全部能够访问到的对象打上标记, 而后清扫一遍内存空间,把全部没标记的对象释放。 '分代技术' 分代回收的总体思想是: 将系统中的全部内存块根据其存活时间划分为不一样的集合,每一个集合就成为一个“代”, 垃圾收集频率随着“代”的存活时间的增大而减少,存活时间一般利用通过几回垃圾回收来度量。
可变数据类型:列表、字典、可变集合
不可变数据类型:数字、字符串、元组、不可变集合
def multipliers(): return [lambda x:i*x for i in range(4)] print([m(2) for m in multipliers()])
#解释:
函数返回值为一个列表表达式,通过4次循环结果为包含四个lambda函数的列表, 因为函数未被调用,循环中的i值未被写入函数,通过屡次替代,循环结束后i值为3, 故结果为:6,6,6,6
现有两个元组(('a'),('b')),(('c'),('d')),请使用python中匿名函数生成列表[{'a':'c'},{'b':'d'}]
#匿名函数形式: l1=(('a'),('b')) l2=(('c'),('d')) ret=map(lambda n:{n[0]:n[1]},zip(l1,l2)) print(list(ret)) #列表表达式形式: l1=(('a'),('b')) l2=(('c'),('d')) print([{n[0]:n[1]} for n in zip(l1,l2)])
v = dict.fromkeys(['k1', 'k2'], []) v['k1'].append(666) print(v) v['k1'] = 777 print(v)
结果: {'k1': [666], 'k2': [666]} {'k1': 777, 'k2': [666]} 解释: Python 字典(Dictionary) fromkeys() 函数用于建立一个新字典,以序列seq中元素作字典的键,value为字典全部键对应的初始值,默认为None。
由于全部键对应同一个值,因此对键为‘k1’的值作了添加操做后,其余几个键的值也都添加了相同的值 v1 = dict.fromkeys(['k1', 'k2']) print(v1) # {'k1': None, 'k2': None} v2 = dict.fromkeys(['k1', 'k2'], []) print(v2) # {'k1': [], 'k2': []}
根据函数对指定序列作映射 map()函数接收两个参数,一个是函数,一个是可迭代对象,map将传入的函数依次做用到序列的每一个元素,并把结果做为新的list返回。 返回值: Python2 返回列表 Python3 返回迭代器 例子1: def mul(x): return x*x n=[1,2,3,4,5] res=list(map(mul,n)) print(res) #[1, 4, 9, 16, 25] 例子2:abs() 返回数字的绝对值 ret = map(abs,[-1,-5,6,-7]) print(list(ret)) # [1, 5, 6, 7]
filter()函数接收一个函数 f(函数)和一个list(可迭代对象),这个函数 f的做用是对每一个元素进行判断,返回 True或 False, filter()根据判断结果自动过滤掉不符合条件的元素,返回由符合条件元素组成的新list。 def is_odd(x): return x % 2 == 1 v=list(filter(is_odd, [1, 4, 6, 7, 9, 12, 17])) print(v) #[1, 7, 9, 17]
''' reduce() 函数 reduce() 函数会对参数序列中元素进行累积 函数将一个数据集合(链表、元组等)中的全部数据进行下列操做 ''' 注意: Python3已经将reduce() 函数从全局名字空间里移除了,
它如今被放置在 fucntools 模块里,若是想要使用它,则须要经过引入 functools 模块来调用 reduce() 函数: from functools import reduce
def add(x,y): return x + y
print(reduce(add,[1,2,3,4,5])) # 15 print(reduce(lambda x, y: x+y, [1,2,3,4,5])) # 15 print(reduce(add,range(1,101))) # 5050
# zip 拉链函数, # 将对象中对应的元素打包成一个个元组, # 而后返回由这些元组组成的列表迭代器。 # 若是各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同。 print(list(zip([0,1,3],[5,6,7],['a','b']))) # [(0, 5, 'a'), (1, 6, 'b')]
zip() 函数用于将可迭代的对象做为参数,将对象中对应的元素打包成一个个元组,而后返回由这些元组组成的列表。 >>>a = [1,2,3] >>> b = [4,5,6] >>> c = [4,5,6,7,8] >>> zipped = zip(a,b) # 打包为元组的列表 [(1, 4), (2, 5), (3, 6)] >>> zip(a,c) # 元素个数与最短的列表一致 [(1, 4), (2, 5), (3, 6)] >>> zip(*zipped) # 与 zip 相反,可理解为解压,返回二维矩阵式 [(1, 2, 3), (4, 5, 6)]
isinstance() 函数来判断一个对象是不是一个已知的类型,相似 type()。
isinstance() 与 type() 区别: type() 不会认为子类是一种父类类型,不考虑继承关系。 isinstance() 会认为子类是一种父类类型,考虑继承关系。 若是要判断两个类型是否相同推荐使用 isinstance()。
# 例一 a = 2 print(isinstance(a,int)) # True print(isinstance(a,str)) # False # type() 与 isinstance() 区别 class A: pass class B(A): pass print("isinstance",isinstance(A(),A)) # isinstance True print("type",type(A()) == A) # type True print('isinstance',isinstance(B(),A) ) # isinstance True print('type',type(B()) == A) # type False
# map:遍历序列,为每个序列进行操做,获取一个新的序列 a = ["123", "sb_sdsd", "sb_456"] b = map(lambda i: i+("sb"), a) print(list(b)) # ['123sb', 'sb_sdsdsb', 'sb_456sb'] # reduce:对于序列里面的全部元素进行累计操做,可带初始值 a = [1, 2, 3] from functools import reduce b = reduce(lambda i, j: i * j, a, 5) print(b) # 30 # filter:对序列里面的元素进行判断筛选,最终获取符合条件的序列。 a = ["123", "sb_sdsd", "sb_456"] b = filter(lambda i: i.startswith("sb"), a) print(list(b)) # ["sb_sdsd", "sb_456"]
print('\n'.join([' '.join(['%s*%s=%-2s' % (j, i, i * j) for j in range(1, i + 1)]) for i in range(1, 10)]))
# a、能够在pycharm的settings里面手动下载添加第三方模块 # b、能够在cmd终端下用pip insatll 安装 # 用过的第三方模块:requests、pymysql、DBUtils等
requests,pymysql,DbUtils,SQLAlchemy
re:正则 os:提供了一种方便的使用操做系统函数的方法。 sys:可供访问由解释器使用或维护的变量和与解释器进行交互的函数。 random:随机数 json:序列化 time:时间
re.match 尝试从字符串的起始位置匹配一个模式,若是不是起始位置匹配成功的话,match()就返回none。
re.search 扫描整个字符串并返回第一个成功的匹配。
匹配一个字符串没有节制,能匹配多少就去匹配多少,直到没有匹配的为止
a. [ i % 2 for i in range(10) ]
b. ( i % 2 for i in range(10) )
# a结果是一个列表生成式,结果是一个列表(i % 2为生成的元素): [0, 1, 0, 1, 0, 1, 0, 1, 0, 1] # b结果是一个生成器
a. 1 or 2 b. 1 and 2 c. 1 < (2==2) d. 1 < 2 == 2
>>> 1 or 2 1 >>> 1 and 2 2 >>> 1 < (2==2) False >>> 1 < 2 == 2 True
def func(a,b = []): b.append(1) print(a,b) func(a=2) func(2) func(2) ''' 2 [1] 2 [1, 1] 2 [1, 1, 1] 函数的默认参数是一个list 当第一次执行的时候实例化了一个list 第二次执行仍是用第一次执行的时候实例化的地址存储 因此三次执行的结果就是 [1, 1, 1] 想每次执行只输出[1] ,默认参数应该设置为None 函数传参为列表陷阱,列表是可变数据类型,可能会在过程当中修改里面的值 '''
list("1,2,3".split(','))
[int(x) for x in ['1','2','3']] a = ['1','2','3'] b = [int(i) for i in a] print(b) # [1, 2, 3]
前两个元素是 int
最后一个元素是元祖
>>> a = (1) >>> type(a) <class 'int'> >>> a = (1,) >>> type(a) <class 'tuple'> >>>
a = [1,2,3,4,5] b = a b1 = a[:] print(b) # [1, 2, 3, 4, 5] b.append(6) print("a",a) # a [1, 2, 3, 4, 5, 6] print("b",b) # b [1, 2, 3, 4, 5, 6] 传递引用 print("b1",b1) # b1 [1, 2, 3, 4, 5] 拷贝
A = [2,3,4]
B = zip(A, A[1:]+A[:1])
[i*i for i in range(1,11)]
list(set([1, 2, 3, 4, 45, 1, 2, 343, 2, 2]))
python中的global语句是被用来声明全局变量的。
x = 2 def func(): global x x = 1 return x func() print(x) # 1
logging
模块定义的函数和类为应用程序和库的开发实现了一个灵活的事件日志系统
# 做用: 管理咱们程序的执行日志,省去用print记录操做日志的操做,而且能够将标准输入输出保存到日志文件 # 场景: 爬虫爬取数据时,对爬取进行日志记录,方便分析、排错。
Stack() 建立一个新的空栈
push(item) 添加一个新的元素item到栈顶
pop() 弹出栈顶元素
peek() 返回栈顶元素
is_empty() 判断栈是否为空
size() 返回栈的元素个数
class Stack: def __init__(self): self.items = [] def is_empty(self): # 判断是否为空 return self.items == [] def push(self,item): # 加入元素 self.items.append(item) def pop(self): # 弹出元素 return self.items.pop() def peek(self): # 返回栈顶元素 return self.items[len(self.items)-1] def size(self): # 返回栈的大小 return len(self.items) if __name__ == "__main__": stack = Stack() stack.push("H") stack.push("E") stack.push("L") print(stack.size()) # 3 print(stack.peek()) # L print(stack.pop()) # L print(stack.pop()) # E print(stack.pop()) # H
%d 表示那个位置是整数;%f 表示浮点数;%s 表示字符串。php
print('Hello,%s' % 'Python') print('Hello,%d%s%.2f' % (666, 'Python', 9.99)) # 打印:Hello,666Python10.00
print('{k} is {v}'.format(k='python', v='easy')) # 经过关键字 print('{0} is {1}'.format('python', 'easy')) # 经过关键字
python 3.7 加入的新特性,基于 format 的简易加强版html
a = yangtuo b = f"{a} is good~~" print(a) # yangtuo is good~~
内部有__next__和__iter__方法的对象,帮助咱们向后一个一个取值,迭代器不必定是生成器
应用场景: - wtforms里面对form对象进行循环时,显示form中包含的全部字段 - 列表、字典、元组 (可让一个对象被for循环)
一个函数内部存在yield关键字 应用场景: - rang/xrange - redis获取值 - conn = Redis(......) - v=conn.hscan_iter() # 内部经过yield 来返回值 - stark组件中 - 前端调用后端的yield
conn = Redis(...) def hscan_iter(self, name, match=None, count=None): """ Make an iterator using the HSCAN command so that the client doesn't need to remember the cursor position. ``match`` allows for filtering the keys by pattern ``count`` allows for hint the minimum number of returns """ cursor = '0' while cursor != 0: # 去redis中获取数据:12 # cursor,下一次取的位置 # data:本地获取的12条数数据 cursor, data = self.hscan(name, cursor=cursor,match=match, count=count) for item in data.items(): yield item
def index(request): data = [ {'k1':1,'name':'alex'}, {'k1':2,'name':'老男孩'}, {'k1':3,'name':'小男孩'}, ] new_data = [] for item in data: item['email'] = "xxx@qq.com" new_data.append(item) return render(request,'xx.html',{'data':new_data})
可以在不修改原函数代码的基础上,在执行先后进行定制操做,闭包函数的一种应用
场景: - flask 路由系统 - flask before_request - csrf - django 内置认证 - django 缓存
# 手写装饰器; import functools def wrapper(func): @functools.wraps(func) #不改变原函数属性 def inner(*args, **kwargs): 执行函数前 return func(*args, **kwargs) 执行函数后 return inner 1. 执行wapper函数,并将被装饰的函数当作参数。 wapper(index) 2. 将第一步的返回值,从新赋值给 新index = wapper(老index) @wrapper #index=wrapper(index) def index(x): return x+100
调用装饰器实际上是一个闭包函数,为其余函数添加附加功能,不修改被修改的源代码和不修改被修饰的方式,装饰器的返回值也是一个函数对象。
好比:插入日志、性能测试、事物处理、缓存、权限验证等,有了装饰器,就能够抽离出大量与函数功能自己无关的雷同代码并继续重用。
字典,元祖,列表等
二分查找算法:
简单的说,就是将一个列表先排序好,好比按照从小到大的顺序排列好,
当给定一个数据,好比3,查找3在列表中的位置时,
能够先找到列表中间的数li[middle]和3进行比较,
当它比3小时,那么3必定是在列表的右边,
反之,则3在列表的左边,好比它比3小,
则下次就能够只比较[middle+1, end]的数,
继续使用二分法,将它一分为二,直到找到3这个数返回或者列表所有遍历完成(3不在列表中) 优势:效率高,时间复杂度为O(logN); 缺点:数据要是有序的,顺序存储。
def binary_chop(alist, data): n = len(alist) if n < 1: return False mid = n // 2 if alist[mid] > data: return binary_chop(alist[0:mid], data) elif alist[mid] < data: return binary_chop(alist[mid + 1:], data) else: return True lis = [2, 4, 5, 12, 14, 23] print(binary_chop(lis, 2))
# 闭包函数就是内部的函数调用外部函数的变量,经常使用于装饰器。 # 判断闭包函数的方法:__closure__,输出的__closure__有cell元素说明是闭包函数 # 闭包的意义与应用:
# 延迟计算
os模块负责程序与操做系统的交互,提供了访问操做系统底层的接口;
sys模块负责程序与python解释器的交互,提供了一系列的函数和变量,用于操控python的运行时环境。
import random print(random.random()) # 用于生成一个0到1的随机符点数: 0 <= n < 1.0 print(random.randint(1, 1000)) # 用于生成一个指定范围内的整数
import os file = r'D:\test.txt' if os.path.exists(file): os.remove(file) print('delete success') else: print('no such file:%s' % file)
先随便扯些和别的语言的对比 python 自己是支持函数式编程 和 面向对象式编程 c,java是只能基于面向对象 在简单说下面向对象的主要特色和好处 - 基础:面向对象自己拥有基础的三大特性 封装 将方法封装到类中 体如今 功能类上的整合 将数据封装到对象中 体如今类的对象初始化赋值等 继承 python 是支持多继承的 是python的一个特点,java c# 是不支持的 基于 mro 的顺序来决定继承顺序 多个类的对共同方法的,为避免重复编写,封装到父(基)类中 应用 : rest framework 中的视图类的继承很是多 多态 python 做为强类型的动态脚本语言,不支持多态,可是也不须要支持多态 在c# java里面必需要指定类型,固然也能够经过接口类实现目的 鸭子类型: python 中的参数能够传入任何类型的对象,不会对类型进行强制限制 说法: 若是我有个类,这个类的传入参数是不会有类型限制的 这体现了多态 我有多个类,这些都有个 send 方法 每一个类的分别的实例化对象在调用 send 的时候 都是obj.send() 的同样的调用方式,可是倒是执行的他内部的本身的 send 方法,这体现了多态性 - 进阶:魔法方法 __init__ 初始化 __new__ 建立对象 __call__ 对象() __str__ print(对象) __repr__ __iter__ 含有此方法且返回迭代器 表明此对象可迭代 __getattr__ 对象.xx __setattr__ __delattr__ 对象.del __setiter__ 对象["xx"] __getiter__ __deliter__ __mro__ 查当作员顺序 __dict__ 查当作员顺序 __add__ 对象相加的时候触发 __...__ 对象相减的时候触发 __...__ 对象相乘的时候触发 __...__ 对象相除的时候触发 __enter__ with 对象的开始前触发 __exit__ with 对象的结束时触发 应用: 在 SQLAlchemy 中有使用 - 高阶:metaclass 类的建立两种方法: class Foo():pass type("Foo",(object,),{ }) 指定建立类的 mtype class Foo(metaclass=MyType): # python 3 # __metaclass__ = MyType # python 2 pass MyType('Foo',(object,),{}) # 若是一类本身或基类中指定了metaclass # 那么该类就是由metaclass指定的type或mytype建立。 对于源码的阅读须要注意 是否指定了 metaclass 未指定直接看 __new__ 而后 __init__ 便可 若是指定了须要注意: 建立类 MyType.__init__ 建立对象 MyType.__call__ MyType.__new__ MyType.__init__
继承概念的实现方式主要有2类:实现继承、接口继承。 实现继承是指使用基类的属性和方法而无需额外编码的能力; 接口继承是指仅使用属性和方法的名称、可是子类必须提供实现的能力(子类重构爹类方法);
python 两种类:经典类 新式类 python3 新式类 —— 都默认继承object class Animal(object): == class Animal: python2 经典类和新式类 并存 class Animal: 经典类 —— 继承顺序 个别使用方法 class Animal(object): 新式类 继承分为单继承和多继承 Python是支持多继承的 若是没有指定基类,python的类会默认继承object类,
object是全部python类的基类,它提供了一些常见方法(如__str__)的实现。
class A: def get(self): self.say() def say(self): print('AAAAA') class B(A): def say(self): print('BBBBB') b = B() b.get() #输出结果为:BBBBB
Python的类能够继承多个类,Python的类若是继承了多个类,那么其寻找方法的方式有两种
当类是经典类时,多继承状况下,会按照深度优先方式查找 py3
当类是新式类时,多继承状况下,会按照广度优先方式查找 py2
简单点说就是:经典类是纵向查找,新式类是横向查找
经典类和新式类的区别就是,在声明类的时候,新式类须要加上object关键字。在python3中默认全是新式类
用于子类继承基类的方法
装饰器中,会用到;functools.wraps()主要在装饰器中用来装饰函数 Stark上下文管理源码中,走到视图阶段时有用到functools中的偏函数,
request = LocalProxy(partial(_lookup_req_object, 'request'))
# __getattr__ CBV django配置文件 wtforms中的Form()示例化中 将"_fields中的数据封装到From类中"
# __mro__ wtform中 FormMeta中继承类的优先级
# __dict__ 是用来存储对象属性的一个字典,其键为属性名,值为属性的值
# __new__ 实例化可是没有给当前对象 wtforms,字段实例化时返回:不是StringField,而是UnboundField est frawork many=Turn 中的序列化
# __call__ flask 请求的入口app.run() 字段生成标签时:字段.__str__ => 字段.__call__ => 插件.__call__
# __iter__ 循环对象是,自定义__iter__ wtforms中BaseForm中循环全部字段时定义了__iter__
# -metaclass 做用:用于指定当前类使用哪一个类来建立 场景:在类建立以前定制操做 示例:wtforms中,对字段进行排序。
# 看他的调用者是谁,若是是类,须要传入参数self,这时就是一个函数; # 若是调用者是对象,不须要传入参数值self,这时是一个方法。 (FunctionType/MethodType)
print(isinstance(obj.func, FunctionType)) # False print(isinstance(obj.func, MethodType)) # True
@property 将方法变成变量形式自动调用
@staticmethod 静态方法,类能够不用实例化就能够调用该方法 C.f(),固然也能够实例化后调用 C().f()。
@classmethod 类不需实例化就能够调用内部方法,直接类名.方法便可调用
Classmethod必须有一个指向类对象的引用做为第一个参数; @classmethod def class_func(cls): """ 定义类方法,至少有一个cls参数 """ print('类方法') --------------------------------------------------------- Staticmethod能够没有任何参数。 @staticmethod def static_func(): """ 定义静态方法 ,无默认参数""" print('静态方法')
1. __doc__:表示类的描述信息。 2.__module__:表示当前操做的对象在那个模块; 3.__class__:表示当前操做的对象的类是什么。 4.__init__:构造方法,经过类建立对象时,自动触发执行。 5.__call__:对象后面加括号,触发执行。 6.__dict__:类或对象中的全部成员。 7.__str__:若是一个类中定义了__str__方法,那么在打印对象时,默认输出该方法的返回值。 class Foo: def __str__(self): return 'aaa' obj = Foo() print(obj) # 输出:aaa 8.__getitem__、__setitem__、__delitem__:用于索引操做,如字典。以上分别表示获取、设置、删除数据。 9.__iter__:用于迭代器,之因此列表、字典、元组能够进行for循环,是由于类型内部定义了 __iter__。
题意理解:组成后的数值不相同,且组合的三个位数之间数字不重复。
使用python内置的排列组合函数(不放回抽样排列)
product 笛卡尔积 (有放回抽样排列)
permutations 排列 (不放回抽样排列)
combinations 组合,没有重复 (不放回抽样组合)
combinations_with_replacement 组合,有重复 (有放回抽样组合)
import itertools print(len(list(itertools.permutations('12345', 3)))) # 60
反射的核心本质就是以字符串的形式去导入个模块,利用字符串的形式去执行函数。
Django中的 CBV就是基于反射实现的。
rest framework里面的CBV
# metaclass 实例 class MyType(type): def __init__(self,*args,**kwargs): super(MyType,self).__init__(*args,**kwargs) def __call__(cls, *args, **kwargs): obj = cls.__new__(cls) cls.__init__(obj,*args, **kwargs) return obj class Foo(object,metaclass=MyType): # metaclass 指定由谁来建立这个类 a1 = 123 def __init__(self): pass def __new__(cls, *args, **kwargs): return object.__new__(cls) def func(self): return 666 foo = Foo() # 建立类的时候会先执行 type 的 __init__ 方法 ,由type 的 __init__ 来建立类 # 当一个类在实例化时候,先执行 type 的 __call__ 方法 , __call__ 方法 的返回值就是实例化对象 # __call__ 内部调用: # 类.__new__ 方法 :建立对象 # 类.__init__ 方法 :对象初始化
# 单例模式 '''单例模式是一种经常使用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。 经过单例模式能够保证系统中一个类只有一个实例并且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。 若是但愿在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。''' # 一、使用__new__方法 class MyClass(object): _instance = False def __new__(cls, *args, **kwargs): if not cls._instance: cls._instance = object.__new__(MyClass) return cls._instance # 二、共享属性 # 建立实例时把全部实例的__dict__指向同一个字典,这样它们具备相同的属性和方法. class Borg(object): _state = {} def __new__(cls, *args, **kw): ob = super(Borg, cls).__new__(cls, *args, **kw) ob.__dict__ = cls._state return ob class MyClass2(Borg): a = 1 # 三、装饰器版本 def singleton(cls, *args, **kw): instances = {} def getinstance(): if cls not in instances: instances[cls] = cls(*args, **kw) return instances[cls] return getinstance @singleton class MyClass: ... # 四、import方法 # 做为python的模块是自然的单例模式 # mysingleton.py class My_Singleton(object): def foo(self): pass my_singleton = My_Singleton() # to use from mysingleton import my_singleton my_singleton.foo()