python 进阶
Posted 刍荛采葑菲
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python 进阶相关的知识,希望对你有一定的参考价值。
1、python特殊函数:
以 __ 开头且以 __ 结尾。
2、__getattr__ 和 __setattr__
__getattr__:拦截点号运算。当对未定义的属性名称和实例进行点号运算时,就会用属性名作为字符串调用这个方法。如果继承树可以找到该属性,则不调用此方法。
class empty: def__getattr__(self, attrname): if attrname =="age": return 40; else: raise AttributeError, attrname x = empty(); print(x.age) #40 print(x.name) #error text omitted.....AttributeError, name
__setattr__:会拦截所有属性的的赋值语句。如果定义了这个方法,self.arrt = value 就会变成self,__setattr__("attr", value).这个需要注意。当在__setattr__方法内对属性进行赋值是,不可使用self.attr = value,因为他会再次调用self,__setattr__("attr", value),则会形成无穷递归循环,最后导致堆栈溢出异常。应该通过对属性字典做索引运算来赋值任何实例属性,也就是使用self.__dict__[\'name\'] = value.
# Python实现属性私有化的首选方式: class PrivateExc(Exception): pass class Privacy: def__setattr__(self, attrname, value): if attrname inself.privates: raisePrivateExc(attrname, self) else: self.__dict__[attrname]= value classTest1(Privacy): privates= ["age"] classTest2(Privacy): privates= ["name","age"] def__init__(self): self.__dict__["name"]= "sun" x =Test1() y =Test2() x.name = "Tom" #执行成功 x.age =20 #执行失败,产生异常,该属性在privates列表内 y.name = "Mike" #执行失败,产生异常,该属性在privates列表内 y.age =20 #执行成功
class User(): def __init__(self, username, password): self._username = username self._password = password @property def username(self): return self._username @username.setter def username(self, username): self._username = username boy = User("name","pass"); print(boy.username());
4、上下文管理器:
with... as... 代码块
当越界后会有处理
#!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = \'Alpha_Meng\' #--------------------------------------- with open("test.txt","w") as f: print(f.closed); f.write("hello word"); print(f.closed); #此处不需要关闭文件,上下文管理器会自动关闭
任何实现了 __enter__() 和 __exit__() 方法都可以做上下文管理。
所以自定义:
#!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = \'Alpha_Meng\' class User(object): def __init__(self, username, password): self._username = username self._password = password @property def username(self): return self._username @username.setter def username(self, username): self._username = username @property def password(self): return self._password @password.setter def password(self, password): self._password = password def __enter__(self): print(\'auto do something before statements body of with executed\') return self def __exit__(self, exc_type, exc_val, exc_tb): print(\'auto do something after statements body of with executed: \' + self._username); if __name__ == \'__main__\': boy = User(\'shouke\', \'shouke2014\') print(boy.password) with User(\'shouke\', \'2014\') as user: print(user.password) print(\'---------end-----------\') print(user.password)
5、闭包:
#!/usr/bin/env python # -*- coding:utf-8 -*- """ closure example """ __author__ = "Alpha_Meng" def line_conf(a, b): def line(x): return a * x + b; return line; line1 = line_conf(1, 1); line2 = line_conf(4, 5); print(line1(5), line2(5)); >>> 6 25
不带参数的装饰器:
#!/usr/bin/env python # -*- coding:utf-8 -*- """ decorator example """ __author__ = "Alpha_Meng"; # 旧的装饰器(不带参数) def decorator(func): def new_func(a, b): print("input", a, b); return func(a, b); return new_func; # 计算平方和 @decorator def square_sum(a, b): return a ** 2 + b ** 2; # 计算平方差 @decorator def square_diff(a, b): return a ** 2 - b ** 2; print(square_sum(4, 5)); print(square_diff(4, 5)); >>>> input 4 5 >>>> 41 >>>> input 4 5 >>>> -9
带参数的装饰器:
#!/usr/bin/env python # -*- coding:utf-8 -*- """ decorator example """ __author__ = "Alpha_Meng"; # 新的装饰器(带参数) def decorator_str(pre=""): # 旧的装饰器(不带参数) def decorator(func): def new_func(a, b): print(pre + "input", a, b); return func(a, b); return new_func; return decorator; # 计算平方和 @decorator_str("Hi + ") def square_sum(a, b): return a ** 2 + b ** 2; # 计算平方差 @decorator_str("Hi - ") def square_diff(a, b): return a ** 2 - b ** 2; print(square_sum(4, 5)); print(square_diff(4, 5)); >>> Hi + input 4 5 >>> 41 >>> Hi - input 4 5 >>> -9
类装饰器:
#!/usr/bin/env python # -*- coding:utf-8 -*- """ decorator class example """ __author__ = "Alpha_Meng"; def decorator(aClass): class NewClass(): def __init__(self, age): self.total_display = 0; self.wrapped = aClass(age); def display(self): self.total_display += 1; print("total display are called ", self.total_display); self.wrapped.display(); return NewClass; @decorator class Bird(): def __init__(self,age): self.age = age; def display(self): print("the age is ", self.age); bird = Bird(5); for i in range(3): bird.display(); >>> total display are called 1 >>> the age is 5 >>> total display are called 2 >>> the age is 5 >>> total display are called 3 >>> the age is 5
7、内存管理
引用计数:
#!/usr/bin/env python # -*- coding:utf-8 -*- from sys import getrefcount; """ 引用计数 reference count example """ __author__ = "Alpha_Meng" # -------- 引用计数 --------------- a = [1,2,3]; print(getrefcount(a)); b = [a,a]; print(getrefcount(a)); # ---------对象引用对象,指向同一对象------------- class FromObj(): def __init__(self,to_obj): self.to_obj = to_obj; x = [1,2,3]; y = FromObj(x); print(id(x)); print(id(y.to_obj)); print(id(x) == id(y.to_obj)); >>> 2 >>> 4 >>> 473473615880 >>> 473473615880 >>> True
GC机制:
#!/usr/bin/env python # -*- coding:utf-8 -*- from sys import getrefcount; """ 垃圾回收 garbage collection example 到达一个阈值会触发垃圾回收,阈值可以设置。 分代回收策略(分为三代,分为0代,1代,2代),类似java的GC 孤立“引用环”问题: 对象在内存中被删除,需要一个条件:那就是该对象被删除且引用计数为0。 当对象A引用对象B,而对象B又引用对象A,那么会形成一个环状引用。即使删除了对象A和对象B,也不会被删除。 在python 使用了一个机制来解决: 系统中会自动复制对象的引用计数,来单独保存计数。 当对象被删除时,会将对象的所有引用计数都减去1,则即使是环状,也都减成了0。 """ __author__ = "Alpha_Meng" a = []; b = [a]; a.append(b); print(getrefcount(a)) print(getrefcount(b)) del a; del b; print(getrefcount(a)) print(getrefcount(b)) >>> 3 >>> 3 >>> Traceback (most recent call last): >>> File "F:/python_workspace/zxga/oop/garbage_collection.py", line 36, in <module> >>> print(getrefcount(a)) >>> NameError: name \'a\' is not defined
8、循环设计
1、循环对象:包含一个next()方法的对象,在穷举完成后,抛出StopIteration错误。
>>> f = open("test.txt"); >>> next(f) \'123\\n\' >>> next(f) \'234\\n\' >>> next(f) \'345\' >>> next(f) Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration
2、迭代器: 用iter() 函数返回迭代器对象。
>>> a = [1,2,3] >>> b = iter(a) >>> next(b) 1 >>> next(b) 2 >>> next(b) 3 >>> next(b) Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration
3、生成器:帮助用户自定义构建循环对象。
yield关键字:程序碰到yield时,会返回;下一次再进入时,从该yield位置后的代码开始执行。
def gen(): a = 10; yield a; a = a*10; yield a; a = 200; yield a; for i in gen(): print(i); >>> 10 >>> 100 >>> 200
生成器表达式(generator expression):
# 生成器表达式: G = (x**2 for x in range(3)); print(next(G)) print(next(G)) print(next(G)) >>> 0 >>> 1 >>> 4
4、表推导(list comprehension):
#!/usr/bin/env python # -*- coding:utf-8 -*- """ 表推导 list comprehension example 格式如下: variable = [out_exp_res for out_exp in input_list if out_exp == 2] 列表对象 = [输出的表达式 for i in list if条件] """ __author__ = "Alpha_Meng" list = [i**2 for i in range(10) if i%2 == 1]; print(list) >>> [1, 9, 25, 49, 81]
5、除了列表推导式 还有 字典推导式、集合推导式
9、动态类型:
1、值传递 和 址传递(引用传递)
#!/usr/bin/env python # -*- coding:utf-8 -*- """ 参数传递 function pass example """ __author__ = "Alpha_Meng"; # ------ 值传递 ------ a = 1; def change_integer(a): a = a + 1; return a; # ------ 引用传递 ------ b = [1, 2, 3] def change_list(b): b[0] = b[0] + 1 return b; print(a); print(change_integer(a)); print(a); print(b); print(change_list(b)); print(b); >>> 1 >>> 2 >>> 1 >>> [1, 2, 3] >>> [2, 2, 3] >>> [2, 2, 3]
10、文件读写:
创建文件: f = open(文件名,模式) 文件对象方法: 读取:f.read(N),f.readLine(),f.readlines() 写入:f.write(str) 关闭:f.close()
11、OOP常见函数:
- hasattr(o,f) # 查看对象o是否包含f属性
- getattr(o,f) # 获取对象o的f属性
- setattr(o,f,new_f) # 将对象o的f属性设置为new_f
- delattr(o,f) # 删除对象o的f属性
- isinstance(o,c) # 对象o是否为类c的实例
- issubclass(c.par) # 类c是否为类par的子类
以上是关于python 进阶的主要内容,如果未能解决你的问题,请参考以下文章
我的C语言学习进阶之旅解决 Visual Studio 2019 报错:错误 C4996 ‘fscanf‘: This function or variable may be unsafe.(代码片段
我的C语言学习进阶之旅解决 Visual Studio 2019 报错:错误 C4996 ‘fscanf‘: This function or variable may be unsafe.(代码片段
我的Android进阶之旅关于Android平台获取文件的mime类型:为啥不传小写后缀名就获取不到mimeType?为啥android 4.4系统获取不到webp格式的mimeType呢?(代码片段
我的Android进阶之旅关于Android平台获取文件的mime类型:为啥不传小写后缀名就获取不到mimeType?为啥android 4.4系统获取不到webp格式的mimeType呢?(代码片段