标签:typeerror 特殊 instance dict app 运算 last ota 它的
# 特殊属性: __name__ 类、方法等名字 __module__ 类定义所在的模块名 __class__ 对象或类所属的类 __bases__ 类的基类的元组,顺序为它们在基类列表出现的顺序 __doc__ 类、方法的文档字符串,没有定义默认为None __mro__ 类的moro,class.mro()返回的结果保存在__mro__中 __dict__ 类或实例的属性,可写的字典 # 查看属性: __dir__: 返回类或者对象的所有成员名称列表。dir()函数就是调用__dir__()。如果提供 __dir__(),则返回属性的列表,否则会尽量从__dict__属性中收集信息。 如果dir([obj])参数包含方法__dir__(),该方法将被调用。如果参数不包含__dir__(),该方法将最大限度地收集参数信息 dir()对于不同类型的对象具有不同的行为: 如果对象是模块对象,列表包含模块的属性名。 如果对象是类型或者类对象,列表包含类的属性名,及它的基类的属性名 否则列表包含对象的属性名,它的类的属性名和类的基类的属性名。 ```python class Foo: def __init__(self, name, age): self.name = name self.age = age def show(self): return self.age x = Foo(‘z‘,12) x.show() print(Foo.__name__) def fn(x): return fn(x-1)+fn(x-2) fn(5) ``` Foo --------------------------------------------------------------------------- RecursionError Traceback (most recent call last) <ipython-input-6-121340e7e479> in <module>() 11 def fn(x): 12 return fn(x-1)+fn(x-2) ---> 13 fn(5) <ipython-input-6-121340e7e479> in fn(x) 10 11 def fn(x): ---> 12 return fn(x-1)+fn(x-2) 13 fn(5) ... last 1 frames repeated, from the frame below ... <ipython-input-6-121340e7e479> in fn(x) 10 11 def fn(x): ---> 12 return fn(x-1)+fn(x-2) 13 fn(5) RecursionError: maximum recursion depth exceeded # 魔术方法: 分类: 1.创建与销毁 __init__ 与 __del__ 2.hash 3.bool 4.可视化 5.运算符重载 6.容器和大小 7.可调用对象 8.上下文管理 9.反射 10.描述器 11.其他 ```python """ 1.__hash__ 内建函数hash()调用的返回值,返回一个整数,如果定义这个方法该类的实例就可hash """ class A: def __init__(self): self.a = ‘a‘ self.b = ‘b‘ def __hash__(self): return 1 def __eq__(self, other): return self.a == other.a print(hash(A())) print((A(),A())) print({A(),A()}) s = {A(),A()} print(s) ``` 1 (<__main__.A object at 0x000001A2B6A2BD30>, <__main__.A object at 0x000001A2B6A2BAC8>) {<__main__.A object at 0x000001A2B6A2BB38>} {<__main__.A object at 0x000001A2B6A2BD30>} # \__eq\__ __eq__ 对应==操作符,判断2个对象是否相等,返回bool值 __hash__方法返回一个hash值作为set的key,但是去重,还需要__eq__来判断2个对象 是否相等 hash值相等,只是hash冲突,不能说明两个对象是相等的。 一般提供__hash__方法是为了作为set或者dict的key的,所以去重 要同时提供__eq__方法 可hash对象必须提供__hash__方法,没有提供的话,isinstance(p1,collections.Hashable) 一定为false __hash__方法返回一个hash值作为set的key,但是去重,还需要__eq__来判断2个对象 是否相等 hash值相等,只是hash冲突,不能说明两个对象是相等的。 一般提供__hash__方法是为了作为set或者dict的key的,所以去重 要同时提供__eq__方法 可hash对象必须提供__hash__方法,没有提供的话,isinstance(p1,collections.Hashable) 一定为false # list类不可hash: 在list类源码中,有一句__hash__ = None,也就是如果调用__hash__()相当于None() 一定报错,。 所有类都继承object,而这个类是具有__hash__()方法 ,如果一个类不能被hash,就是 把__hash__设置为None了。 ```python from collections import Hashable class Point: def __init__(self, x ,y): self.x = x self.y = y def __hash__(self): return hash((self.x, self.y)) def __eq__(self, other): return self.x == other.x and self.y == other.y p1 = Point(4,5) p2 = Point(4,5) print(hash(p1)) print(hash(p2)) print(p1 is p2) print(p1 == p2)c print(set((p1, p2))) print(isinstance(p1, Hashable)) ``` 3713084879518070856 3713084879518070856 False True {<__main__.Point object at 0x000001A2B6AE3898>} True # bool __bool__ 内建函数,或者对象放在逻辑表达式的位置,调用这个函数返回布尔值, 没有定义__bool__(),就找__len__()返回长度,非0为真。如果__len__()也没有定义,那么所有实例返回真 ```python class A: pass print(bool(A())) class B: def __bool__(self): return False print(bool(B))#类 print(bool((B())))#实例 class C: def __len__(self): return 0 print(bool(C())) ``` True True False False # 可视化 __repr__ 内建函数rer()对一个对象获取字符串表达。如果一个类定义了__repr__()但没有定义__str__,那么在请求该类的实例的‘非正式‘的字符串也将调用__repr__() __str__ str()函数,内建函数format、print()函数调用,需要返回对象的字符串表达 __bytes__ bytes的时候,返回一个对象的bytes表达,即返回Bytes对象 ```python class A: def __init__(self): self.a = ‘a‘ self.b = ‘b‘ def __repr__(self): return ‘repr: {}, {}‘.format(self.a, self.b) def __str__(self): return ‘str: {}, {}‘.format(self.a, self.b) print(A()) print([A()]) print(([str(A())])) print(‘str:a,b‘) s = ‘b‘ print([‘a‘], (s,)) ``` str: a, b [repr: a, b] [‘str: a, b‘] str:a,b [‘a‘] (‘b‘,) # 运算符重载 ```python ‘实例的减法‘ class A: def __init__(self, x): self.x = x def __sub__(self, other):#减法 return self.x - other.x def __ne__(self, other): return self.x != other.x def __eq__(self, other): return self.x == other.x a1 = A(4) a2 = A(4) a1-a2 # 等价于 a1.__sub__(a2) print(a1 == a2) print(a1 != a2) ``` True False ```python class Point: """ __sub__ 相等 __add__ 相加 __str__ 格式化字符串 """ def __init__(self, x, y): self.x = x self.y = y def __eq__(self, other): return self.x == self.x and self.y == self.y def __add__(self, other): return (self.x + other.x, self.y + other.y ) def __str__(self): return (self.x and self.y) a = Point(3,5) b = Point(1,2) print(a+b) ``` (4, 7) ```python ‘购物车类改造成方便操作的容器‘ class Cart: def __init__(self): self.items = [] def __len(self): return len(self.items) def additem(self, item): self.items.append(item) def __iter__(self): return iter(self.items) def __getitem__(self, item): return self.items[item] def __setitem__(self, key, value): self.items[key] = value cart = Cart() cart.additem(1) ``` # 可调用对象: 在python中,一切皆对象 函数也是 __call__ 实例可以像函数一样被调用 ```python def foo(x): print(x) foo(5) print(foo.__dict__) print(foo.__call__(5)) print(dir(foo)) ``` 5 {} 5 None [‘__annotations__‘, ‘__call__‘, ‘__class__‘, ‘__closure__‘, ‘__code__‘, ‘__defaults__‘, ‘__delattr__‘, ‘__dict__‘, ‘__dir__‘, ‘__doc__‘, ‘__eq__‘, ‘__format__‘, ‘__ge__‘, ‘__get__‘, ‘__getattribute__‘, ‘__globals__‘, ‘__gt__‘, ‘__hash__‘, ‘__init__‘, ‘__kwdefaults__‘, ‘__le__‘, ‘__lt__‘, ‘__module__‘, ‘__name__‘, ‘__ne__‘, ‘__new__‘, ‘__qualname__‘, ‘__reduce__‘, ‘__reduce_ex__‘, ‘__repr__‘, ‘__setattr__‘, ‘__sizeof__‘, ‘__str__‘, ‘__subclasshook__‘] ```python class A: def __call__(self, *args, **kwargs): print(5 A()() # a = A() a() ``` 5 ```python class Point: def __init__(self, x, y): self.x = x self.y = y def __call__(self, *args, **kwargs): return "" ``` ```python class Fib: def __init__(self): self.numlst = [0,1] def fib_iter(self, value): for i in range(value - 2): self.numlst.append(self.numlst[-2] + self.numlst[-1]) return self.numlst x = Fib() x.fib_iter(10) ``` ```python class Fib: """ f(n-1) + f(n-2) """ def __init__(self): self.lst = [0,1] def fib_iter(self, values): ret = 0 for i in range(values - 2): self.lst.append(self.lst[-2] + self.lst[-1]) return self.lst f = Fib() f.fib_iter(9) ``` [0, 1, 1, 2, 3, 5, 8, 13, 21] ```python class Fib: """ f(n-1) + f(n-2) """ def __init__(self): self.lst = [0,1,1] def __call__(self, value): if value < len(self.lst): # 返回对象的长度减少计算量 return self.lst for i in range(len(self.lst),value): self.lst.append(self.lst[i-1] + self.lst[i-2]) return self.lst def __getitem__(self,index):#取索引 a[x] = xx if index < 0: return None if index < len(self.lst): return self.lst[index] else: self(index) def __iter__(self): return iter(self.lst) #可以迭代 fib = Fib() fib(20) for i in fib: print(i) ``` 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 # 上下文管理: __enter__ 进入与此对象(实例)相关的上下文。如果存在该方法,with语法会把该方法的值作为绑定到as子句中指定的变量上 __exit__ 退出与此对象相关的上下文 实例化对象的时候,不会调用enter,进入with语句块调用enter方法,然后执行语句体,最后离开with语句块的时候。调用exit方法 with可以开启一个上下文运行环境,在执行前做一些准备工作,执行后做一些收尾工作 上下文应用场景: 1、增强功能 在代码执行的前后增加代码,以增强其功能,类似装饰器 2、资源管理 打开了资源需要关闭,例如文件对象,网络连接,数据库连接等 3、权限验证 在执行代码之前,做权限的验证,在__enter__中处理 ```python class Point: """ __enter__ 进去做的事情 __exit__ 退出做的事情 """ 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__) print(exc_type)#异常类型 print(exc_val)#异常的值 print(exc_tb)#异常的追踪信息 return 0#返回一个等效的值 True压制 False抛出异常 p = Point() with p as f: raise Exception(‘Error-zz‘) print(f == p)#enter如果没有返回值 就为False print(f is p) print(‘outer‘) ``` init <class ‘__main__.Point‘> Point <class ‘Exception‘> Error-zz <traceback object at 0x0000019117DA9C48> --------------------------------------------------------------------------- Exception Traceback (most recent call last) <ipython-input-227-cf8294135f8a> in <module>() 18 p = Point() 19 with p as f: ---> 20 raise Exception(‘Error-zz‘) 21 print(f == p)#enter如果没有返回值 就为False 22 print(f is p) Exception: Error-zz ```python import datetime import time def times(fn): def wrapper(*args, **kwargs): start = datetime.datetime.now() print(args, kwargs) ret = fn(*args,**kwargs) after = datetime.datetime.now() - start return ret return wrapper @times def add(x, y): time.sleep(2) return x + y print(add(2,y=4)) ``` (2,) {‘y‘: 4} 6 ```python import time import datetime from functools import wraps class TimeIt: def __init__(self, fn): self._fn = fn def __enter__(self): print(‘enter‘) self.start = datetime.datetime.now() return self def __call__(self, *args, **kwargs): print(‘call‘) start = datetime.datetime.now() print(args, kwargs) ret = self._fn(*args, **kwargs) delta = datetime.datetime.now() - start print(‘took{} s‘.format(delta)) return ret #return self.fn(*args, **kwargs) def __exit__(self, exc_type, exc_val, exc_tb): delta = (datetime.datetime.now() - self.start).total_seconds() print(‘exit‘) print(delta) return # def times(fn): # @wraps(fn) # def wrapper(*args, **kwargs): # start = datetime.datetime.now() # print(args, kwargs) # ret = fn(*args,**kwargs) # after = datetime.datetime.now() - start # return ret # return wrapper # @times @TimeIt# add = TimeIt(add) def add(x, y): time.sleep(2) return x + y add(3,4) # with TimeIt(add) as foo: # print(foo(5,3)) ``` call (3, 4) {} took0:00:02.000684 s --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-299-034e034cf759> in <module>() 42 return x + y 43 add(3,4) ---> 44 add.__doc__() 45 # with TimeIt(add) as foo: 46 # print(foo(5,3)) TypeError: ‘NoneType‘ object is not callable # Contextlib.contextmanager 它是一个装饰器实现上下文管理,装饰一个函数,不用像类一样实现__enter__和__exit__方法。 对下面的函数有要求,必须有yield,也就是这个函数必定返回一个生成器,且只有yield一个值。 ```python import contextlib @contextlib.contextmanager def foo(): print(‘enter‘)# 相当于 __enter__() yield 5 #作为__enter__方法的返回值 print(‘exit‘)#相当于__exit__() with foo() as f: print(f) ‘f接收yield语句的返回值‘ ``` enter 5 exit ‘f接收yield语句的返回值‘ ```python import contextlib @contextlib.contextmanager def foo(): print(‘enter‘) try: yield 5 finally: print(‘exit‘) with foo() as f: raise Exception() print(f) #执行yield,为生成器函数增加了上下文管理 ``` enter exit --------------------------------------------------------------------------- Exception Traceback (most recent call last) <ipython-input-6-cddb091c6a6e> in <module>() 10 print(‘exit‘) 11 with foo() as f: ---> 12 raise Exception() 13 print(f) Exception: ```python import contextlib import datetime import time @contextlib.contextmanager def add(x, y): start = datetime.datetime.now() try: yield x + y finally: delta = (datetime.datetime.now()- start).total_seconds() print(delta) with add(4,5) as f: time.sleep(3) print(f) ‘如果业务逻辑简单可以使用函数加装饰器方式,如果业务复杂,用类的方式加__enter__和__exit__方法方便。‘ ``` 9 3.000015 ‘如果业务逻辑简单可以使用函数加装饰器方式,如果业务复杂,用类的方式加__enter__和__exit__方法方便。‘
标签:typeerror 特殊 instance dict app 运算 last ota 它的
原文地址:http://www.cnblogs.com/hkcs/p/7860712.html