__init__ 初始化方法不要写任何返回语句,他返回的是你的类的实例
特殊属性
__name__ 类和函数的名字
__module__ 类定义所在的模块名
__class__ 对象或类所属的类
__bases__ 类的基类的元组,按列表出现的顺序
__doc__ 类、函数文档字符串,或None
__mro__ class.mro()返回结果保存
__dict__ 类或实例的属性
__dir__方法,查看属性,
返回搜索的内容,尽量多得收集当前模块的信息,可以从一个实例的类以及祖先类上手机信息。内建函数dir()需要用内置的__dir__方法
dir()
如果对象什么都不指定,是模块对象,收集当前模块的
如果指定某个对象,收集指定对象相关的属性,包括类以及祖先类的属性。并且去重。
import test2
print(dir())
print(dir(test2))
print(sorted(set(b.__dict.keys()) | set(b.__class__.__dict__.keys()) | set(object.__dict__)))
魔术方法
创建与销毁
创建与销毁
init__ __del__
python 建立了一个dict存储用来查阅,通过key查阅
用init,添加实例,
del与GC回收有关,我们一般不关心。
hash
python将hash用在了可hash类型中,set
做一个hash散列,hash的时间复杂度是O(1),用在缓存
缓存的作用是存储备用,再次使用。
buffer的作用是拦河坝,协调生产者和消费者之间速度差的。
hash 冲突,hash值相同
hash值相同的用set来装,是否去重
关系运算 is == 分别有什么异同
class A:
X = 123
def __init__(self):
self.y = 5
pass
__hash__ = None # # TypeError: unhashable type: 'A'
print(hash(A()))
先调 is 再调 ==
hash一定会有冲突,最简单用x % 3做 对x hash。可hash并不代表可去重。如果要去重,得看==
c. bool
就两条,如果没有这两条,那么就永远为真的。
可视化
__repr__ ,与__str__几乎不区分,如果缺失了__str__就调用__repr__,如果都没有,就返回object定义,显示内存地址信息。
__str__,str()函数,返回字符串表达,与repr(),__repr__分先后__repr__,repr()对一个对象获取字符串表达,调用__repr__方法返回字符串表达,若__repr__没有定义,就返回object定义,即内存地址信息。
运算符重载
容器和大小
可调用对象
上下文管理
反射
描述器
其他杂项
__eq__ 判断是不是相同的,逻辑运算符,return结果是bool
__bool__,若没有定义__bool__,就调用__len__
运算符重载根据实际需求使用。
class A:
def __init__(self, x):
self.x = x
def __sub__(self, other):
return A(self.x - other.x)
def __ne__(self, other):
return self.x != other.x
def __eq__(self, other):
return self.x == other.x
def __lt__(self, other):
return self.x < other.x
def __repr__(self):
return str(self.x)
def __iadd__(self, other):
# self.x += other.x
# return self a1就地修改
return A(self.x + other.x)一个新的a1实例
a1 = A(4)
a2 = A(10)
lst = [a1, a2]
print(sorted(lst))
容器方法
len 与 size的区别,size指的是容器的大小,len是item的数量。并不相等,大小也不一定。
__len__对应内建函数,len()
__getitem__ 用index或者Key,分别对应使用list,dict ,扔进[ ]一个key,返回对应的item或者value,key不存在KeyError
__setitem__ ,[key],设置一个值给这个key
__missing__ ,类default,
__iter__ 必须返回一个迭代器
用魔术方法实现购物车功能
class Color:
RED = 0
class Item:
def __init__(self, name, **kwargs):
self.name = name
self.__spec = kwargs
def __repr__(self):
return "{} = {}".format(self.name, self.__spec.items()))
class Cart:
def __init__(self):
self.items = []
def additem(self, item:Item):
self.items.append(item)
def getallitems(self):
return self.items
def __getitem__(self, item): # this item is index of items ,Out of range is possible
return Item(self.items[item])
def __missing__(self, key): # dict/set key missing ,list can not use this method
print("key =="key)
def __setitem__(self, key, value):
self.items[key] = value
#self[key] = value 在其他地方可以直接赋值
def __len__(self):
return len(self.items)
def __iter__(self): # 有了这个方法用户可以直接 for x in cart,而不是for x in cart.items
return iter(self.items)
def __add__(self, other):
if isinstance(other, Item)
self.items.append(other)
class MyDict(dict): #建一个字典类
pass
可调用对象,类的实例调用,相当于调用实例的__call__
为什么__call__讲一个类的实例调用,call的第一个pos args是self
函数foo,foo(5)等价于foo.__call__(5)
__repr__ = __str__ str调用就等于repr调用,所以让他们
__repr__ = None 让他的返回值是None 就可以实现相等了
上下文管理
with 开启一个上下文环境,在接下来的网络编程中,socket也当文件来用,有上下文
必须是在一个类上去写,并用在实例上。
class Point:
def __init__(self):
print('init')
def __enter__(self): # 维护了文件资源
print(self.__class__)
return self
def __exit__(self, exc_type, exc_val, exc_tb): #
print(self.__class__.__name__)
p = Point()
import sys
with Point() as f:
print(p == f)
print(p is f)
需要给__enter__ return 一个适当的值,给f
exc_type 类
exc_val 类
exc_tb 返回类True的话,压制异常
上下文的应用场景
增强功能
在代码执行的前后增加代码,类似装饰器的功能。
资源管理
文件对象、网络连接、数据库连接等的关闭
权限验证
权限验证,在__enter__z中处理
add存在与TImeIT的实例C()的参数中,add函数定义不存在了
contextlib.contextmanager
是一个装饰器,也可以实现上下文管理。对函数有要求,必须是一个生成器函数。
yield虽然在字节码上和return有区别,但是可以把它当成return看。
import contextlib
@contextlib.contextmanager
def foo():
print('enter')
yield 3,5 # 必须有yield语句,在yield的发生处切一刀,前后加东西,把yield的返回值放到enter里面,作为返回值。
print('exit')
with foo() as f:
try:
raise Exception
finally:
print(f)
functools @total_ordering ,如果注重效率,就最好不要用。
加上total_ordering用来减少操作,比如定义eq,用total_ordering推演其他比较,如果没有@total无法对进行其他比较。
转载于:https://blog.51cto.com/13320196/2044419