Python高级编程
来源:互联网 发布:网络银行有几家 编辑:程序博客网 时间:2024/06/03 08:50
模块重新导入
当import moduleName
的时候,python是通过sys.path
来查找的。可以使用sys.path.append('newPath')
可以添加搜索路径。
当import了一个module之后,修改了module的代码,那么在当前运行时不会更新module修改后的功能。需要重新导入:
form imp import *reload(moduleName)
- 循环导入:
a import b ,b import a ,导致循环导入,发生错误。解决思路是建一个主模块,建多个子模块,让主模块调用子模块,避免循环导入。
is 和 ==
==是判断两个对象值是否相等
is是判断两个是否指向同一个对象(引用比较)
深拷贝 浅拷贝
浅拷贝:给变量赋值,只将自己的引用赋值给变量,没有赋值。
深拷贝:import copy b = copy.deepcopy(a)
import copy b = copy.copy(a)copy.copy指深拷贝本身变量的值,而不会深拷贝变量里面元素的值;而copy.deepcopy会深拷贝里面的值
copy.copy如果拷贝的是不可变类型,则是浅拷贝。
property
class Test(object): def __init__(self): self.__num = 100 def setNum(self, newNum): print("----setter----") self.__num = newNum def getNum(self): print("----getter----") return self.__num num = property(getNum, setNum) #t.num = 200 #相当于调用了 t.setNum(200) #print(t.num) #相当于调用了 t.getNum()
或者
class Test(object): def __init__(self): self.__num = 100 @property def num(self): print("----getter----") return self.__num @num.setter def num(self, newNum): print("----setter----") self.__num = newNumt = Test()#t.num = 200 #相当于调用了 t.setNum(200)#print(t.num) #相当于调用了 t.getNum()
迭代器
可迭代对象
Iterable
- 一类是集合数据类型:list,tuple,dict,set str
- 一类是generator,包括生成器和带yield的generator function
判断对象是否可以迭代
from collections import Iterableisinstance(Obj,Iterable)
- 迭代器。可以用next()返回下一个值的对象。
Iterator
from collections import Iterableisinstance(Obj,Iterable)
iter()
函数,可以将可迭代对象转成迭代器。
闭包
在函数内部定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包。
def func(var): def func_closure(): print(var*2) return func_closuref = func(123)f()
装饰器
原理:
def auth(func): def inner(): print('验证权限...') func() return innerdef f1(): passdef f2(): passf1 = auth(f1)f1()
应用:语法糖简化调用
def auth(func): print('装饰1...') def inner(): print('验证权限1...') func() return innerdef auth2(func): print('装饰2...') def inner(): print('验证权限2...') func() return inner@auth #相当于 f1 = auth(f1) ->注意装饰器的执行时间@auth2def f1(): pass@authdef f2(): passf1()#@语法糖可以加多个执行结果:装饰2...装饰1...验证权限1...验证权限2...
通用的的装饰器
def decorate(functionName): def funcIn(*args,**kwargs): ret = functionName(*args,**kwargs) return ret return funcIn
装饰器带参数
作用:在运行时起到有不同的功能。
def decorateArgs(pre="hello"): def decorate(functionName): def funcIn(*args,**kwargs): ret = functionName(*args,**kwargs) return ret return funcIn return decorate@decorateArgs("bendeng")def test(): pass
作用域
globals()
查看当前命名空间所有的全局变量。 localls()
查看当前命名空间所有的局部变量。 LEGB
原则:local->enclosing->global->buildins dir(__buildin__)
查看所有内嵌
动态语言
在运行时给对象(类)绑定(添加)属性(方法)。
class Test: passdef test(self): pass#动态添加属性可以直接添加#动态添加方法使用types的MethodType方法import typest.test() = types.MethodType(test,t)#或者xxx = types.MethodType(test,t)t.test()
静态方法和类方法直接添加
@staticmethoddef staticMethod(): pass@classmethoddef classMethod(): passclass Test: passTest.test = staticMethodTest.test = classMethod
__slots__
可以限制class实例能添加的属性
class Person: __slots__ = ("name","age")
生成器
python中一边循环一边计算的机制,叫generator,生成器。
产生原因:生成列表时,如果很大(比如10000000),那么会占用很大的储存空间。根据列表生成规则只生成前面几个,就产生了生成器。
- 生成器创建方法1:
a = (x for x in range(10))
- 生成器创建方法2: 存在
yield
的函数称为生成器
def generator(): b = 0 for i in range(10): yield b #next()一次就执行到这里停顿,b会更新值 b = i * 2a = generator()next(a) <==> a.__next__() #两种方式等价for c in a: #生成器可以放在for循环里执行 pass
send:
def test(): i = 0 while i < 5: temp = yield i print(temp) i += 1t = test()t.__next__() #temp 为Nonet.send('hello') #temp为hello。send可以为temp赋值,相当于yield i的值为'hello'并赋值给temp#第一次调用t.send(None)不会报错
yield作用:多任务。三种多任务方法之一:协程
。
def test1(): while True: print('1') yield Nonedef test2(): while True: print('2') yield Nonet1 = test1()t2 = test2()while True: t1.__next__() t2.__next__()
垃圾回收
- 小整数[5,257)共享对象,常驻内存
- 单个字符共享对象,常驻内存
- 单个单词不可修改,默认开启
intern
机制,共用对象,引用计数为0,则销毁。 - 字符串(含有空格),不可修改,不开启
intern
机制,不共用对象,引用计数为0,销毁。 - 大整数不共用内存,引用计数为0,销毁。
- 数值类型和字符串类型在python中是不可变的,即无法修改一个对象的值,每次对对象的修改,实际上是创建一个新对象。
python采用引用计数
为主,标记-清除
和分代收集
两种机制为辅的策略。
引用计数
- 优点:
- 简单
- 实时性:一旦没有引用,内存就直接被释放。不用像其它机制等到特定时机。实时性还带来一个好处,处理回收内存的时间分摊到了平时。
- 缺点
- 维护引用计数消耗资源
- 循环引用
- 导致引用计数+1 的情况
- 对象被创建,a = “hello”
- 对象被引用,b = a
- 对象被当做参数传入一个函数,func(a)
- 对象作为一个元素,储存在容器中,list=[a,b]
- 导致引用计数-1的情况
- 对象的别名被显示销毁,del a
- 对象的别名被赋予新的对象,a = “world”
- 一个对象离开它的作用域,如局部对象
- 对象所在的容器被销毁,或从容器中删除对象
- 查看一个对象的引用计数
import sysa = "hello world"sys.getrefcount(a)
这里查看a对象的引用计数,会比正常计数大1。
垃圾回收
- 垃圾回收的对象会存放在
gc.garbage
列表里面 gc.collect()
会返回不可达的对象数目。- 三种情况会触发垃圾回收
- 调用gc.collect()
- 当gc模块的计数器达到阈值的时候
- 程序退出的时候
- gc模块常用功能
- 1、gc.set_debug(flag).一般设置为gc.DEBUG_LEAK
- 2、gc.collect()。显示进行垃圾回收
- 3、gc.get_threshould()获取gc模块中自动执行垃圾回收的频率。如(700,10,10)
- 4、gc.set_threshould(threshould0,[threshould1,[threshould2])设置自动执行垃圾回收的频率
- gc.get_count()获取当前自动执行垃圾回收的计数器,返回一个长度为3的列表。例如(465,7,6),465表示距离上一次一代垃圾检查Python分配内存的数目减去释放内存的数目;7指距离上一次二代检查,一代垃圾检查的次数;6是指距离上一次三代垃圾检查,二代垃圾检查的次数。
在Python中,采用分代收集的方法。把对象分为三代,一开始,对象在创建的时候,放在一代中,如果在一次一代的检查中,该对象存活下来,就会被放到二代中,同理在一次二代的检查中,该对象存活下来,就会放到三代中。
gc模块唯一处理不了的是循环引用的类都有
__del__
方法,所以项目中尽量避免定义__del__
方法。
内建属性
class Test(object): def __init__(self,subject1): self.subject1 = subject1 self.subject2 = 'python' #属性访问拦截器 def __getattribute__(self,obj): if(obj == 'subject1'): print('access property subject1') return 'back custom subject1 value' else: #return self.show() 发生递归调用,程序崩溃 return object.__getattribute__(self,obj) def show(self): passt = Test('p')print(t.subject1)print(t.subject2)
强调内容
不要在
__getattribute__
中调用self.xxxx。
内建函数
输入dir(__buildin__)
可以看到很多python解释器启动后默认加载的属性和函数。
常用的内建函数:
- range()
- map():map(func,sequence,[sequence,]),,返回值是list
m = map(lambda x:x*x,[1,2,3])print(list(m)) #结果为[1,4,9]
- filter():对指定序列执行过滤操作。返回值的类型和参数sequence的类型相同
f = filter(lambda x:x%2,[2,3])print(list(f)) #结果为[3]
- reduce():对参数序列中的元素进行累积。
reduce(lambda x,y:x+y,[1,2,3,4])
在python3中,reduce函数从全局名字空间移除了,现在放置在functools模块里。
from functools import reduce
- sorted()
sorted([2,1,3,4]) #[1,2,3,4]sorted([2,1,3,4],reverse=1) #[4,3,2,1]
集合Set
集合与列表、元组类似,可以储存多个数据,但是这些数据是不重复的。
集合对象支持union(联合)、difference(差)和sysmmetric_difference(对称差集)等数学运算。
x = set([1,2,3,4]) #{1,2,3,4}y = set([2,3,5,6,2]) #{2,3,5,6}x & y #交集{2, 3}x | y #并集{1, 2, 3, 4, 5, 6}x ^ y #差集{1, 4, 5, 6}
functools
functools是python2.5引入的。一些工具函数放在此包中。python3中增加了更多的函数,但很多不常用到。下面是常用的两个函数 :
particial
函数(偏函数):把一些函数的某些参数设置成默认值,返回一个新的函数,调用新函数会更简单。
import functoolsdef showValue(*args,**kwargs): print(args) print(kwargs)#p = showValue#p(1,2,3)p = functools.partial(showValue,1,2,3)p() #(1, 2, 3) {}p(id=123) #(1,2,3) {'id':123}
wraps
函数
使用装饰器时,需要注意被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会改变)。
由于函数名和__doc__
变化,对测试结果会有一些影响。
import functoolsdef note(func): '''note function''' #@functools.wraps(func) def wrapper(): '''wrapper function''' print('note something') return func return wrapper@notedef test(): '''test function''' print('test ~')print(test.__name__) #wrapperprint(test.__doc__) #wrapper function
使用@functools.wraps(func)
后,print(test.__doc__)
会返回test function
。
模块进阶
- hashlib
import hashlibm = hashlib.md5()m.update('bendeng')m.hexdigest() #45ac4274cad82274abcfce45f494eea4
常用的扩展库:
Python2中,python -m SimpleHTTPServer PORT
,python3中,python3 -m http.server PORT
。可运行起来静态服务, 用于预览和下载文件。
- 读写Exce文件
1、安装个easy_install工具
sudo apt-get install python-setuptools
2、安装模块
sudo easy_install xlrdsudo easy_install xlwt
调试
pdb是基于命令行的 调试工具,非常类似于GNU的gdb。
- 执行时调试
python -m pdb some.py
- 交互调试,进入pythoo或者ipython:
import pdbpdb.run('testfun(args)')
- 程序里埋点
import pdbpdb.set_trace()
- 日志调试
print
正则表达式
正则表达式是所有语言通用的字符串匹配方式。
python中使用正则表达式:
import re#使用match方法进行匹配操作result = re.match(正则表达式,要匹配的字符串)#提取数据result.group()
match
方法返回匹配对象Match Object
;否则返回None
。
表示单个字符串
\d = [0-9]\D = [^0-9]\w = [a-zA-Z0-9_]\W = [^a-zA-Z0-9_]
表示匹配数量的表达式
* {0,}+ {1,}? {0,1}
Python中使用字符r表示字符使用原始字符。
表示边界:
re.match(r'.{3}\b','ben deng') #benre.match(r'.+\B','bendeng') #benden
匹配分组
匹配任意一个0-100的数字r'[1-9]\d?$|0$|100$'
或r'[1-9]?\d?$|100$'
分组匹配
r = re.match(r'<h1>(.*)</h1><h2>(.*)</h2>','<h1>网页标题</h1><h2>H2文本</h2>')r.group|r.group(0) #'<h1>网页标题</h1><h2>H2文本</h2>'r.group(1) #网页标题r.group(2) #H2文本r.groups() #('网页标题', 'H2文本')
分组别名示例:
#coding=utf-8import rer = re.match(r'<(?P<k1>.+)>.*</(?P=k1)><(?P<k2>.+)>.*</(?P=k2)>','<h1>h1文本</h1><h2>H2文本</h2>')print(r.groups()) #('h1','h2')
高级用法
- search
从左向右搜索拿到第一个结果则停止
import rere.search(r'h\d','<h1>h1文本</h1><h2>H2文本</h2>')# h1
- findall
找到所有匹配的结果
import rere.findall(r'h\d','<h1>h1文本</h1><h2>H2文本</h2>')#['h1', 'h1', 'h1', 'h2', 'h2']
- sub
正则替换
import rere.sub(r'h\d','m','<h1>h1文本</h1><h2>H2文本</h2>')#'<m>m文本</m><m>H2文本</m>'
- split
分割字符串
import rere.split(r'<.+?>','<h1>h1文本</h1><h2>H2文本</h2>')#['', 'h1文本', '', 'H2文本', '']
贪婪和非贪婪模式
正则表达式默认是贪婪模式,使用?使用非贪婪模式。
- 《Python高级编程》读书笔记
- python 高级编程 一
- python 高级编程 二
- python 高级编程 三
- python 高级编程 四
- Python高级编程技巧
- Python高级编程技巧
- Python高级编程技巧
- Python高级编程技巧
- Python高级编程技巧
- Python高级编程技巧
- Python高级编程技巧
- Python高级编程技巧
- Python高级编程技巧
- Python 高级编程技巧
- python高级编程
- Python高级编程技巧
- python高级编程-生成器
- JAVA学习笔记
- POJ
- 最大公约数的相关算法
- chmod权限
- 通用方法 解决/usr/lib64/libstdc++.so.6: version `CXXABI_1.3.8' not found的问题
- Python高级编程
- iOS开发-Protocol协议及委托代理(Delegate)传值
- appium使用过程中遇到的坑
- oracle&&linux技能点记录
- ionic app实现扫描二维码添加好友
- iOS中的delegate的用法和规范
- JDK8新特性:接口的静态方法和默认方法
- Unity 菜单栏
- Docker检查运行中的容器的详细信息