标签: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