python类

摘要

  • 一些类、面向对象的使用方法
  • 类的内置方法

扩展

通过importlib和反射实现用多个路径加载类并执行,可扩展性强

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
###########
MSG_LIST = [
'utils.message.email.Email',
'utils.message.msg.Msg',
]
###########
import settings
import importlib

def send_msg(msg):
for path in settings.MSG_LIST:
m, c = path.rsplit('.', maxsplit=1)
md = importlib.import_module(m)
obj = getattr(md, c)()
obj.send(msg)

用装饰器装饰函数的时候,需要把装饰器放在路由下面,此时如果没设置endpoint,默认的endpoint是装饰器里面的inner函数,但是endpoint不能冲突,因此,此时会报错

  • 可以所有路由设置endpoint来解决
  • 可以给装饰器加@wraps()
1
2
3
4
5
6
7
8
9
def check_login(func):
# 帮助我们设置函数的元信息
@wraps(func)
def inner(*args, **kwargs):
print("after")
res = func(*args, **kwargs)
print("sss")
return res
return inner

偏函数

1
2
3
4
5
6
7
8
import functools

def func(a1,a2):
print(a1,a2)

new_func = functools.partial(func,666)

new_func(999)

面向对象

当面向对象中多有__函数__实现时,对象做任何操作时,都会执行其中对应的方法。

1
2
3
4
5
6
7
8
9
10
11
12
class Foo(object):
def __init__(self, num):
self.num = num

def __add__(self, other):
data = self.num + other.num
return Foo(data)

obj1 = Foo(11)
obj2 = Foo(22)

v = obj1 + obj2

函数列表

拼接列表中的值、类似链

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from itertools import chain

v1 = [11,22,33]
v2 = [44,55,66]

v = chain(v1,v2)
for item in v:
print(item)

########$
from itertools import chain

def f1(x):
return x + 1

func1_list = [f1, lambda x:x-1]

def f2(x):
return x + 10

new_func_list = chain([f2,],func1_list)

for func in new_func_list:
print(func)

私有字段

1
2
3
4
5
6
7
8
9
10
11
class Foo(object):
def __init__(self):
self.name = "xxx"
self.__age = 18

obj = Foo()
print(obj.name)
print(obj._Foo__age)

# 如果写了__setattr__方法设置私有变量的方法
object.__setattr__(self, '_Foo__age',20)

with

1
2
3
4

with Foo() as obj:
# 自动调用类中的__enter__方法,obj就是__enter__的返回值
# 当执行完毕后,自动调用类的__exit__方法

__all__

一个py文件如果有__all__,就只能导入里面指定的方法

1
__all__ = ['abc']

需要单独整理一个类的内置方法详解
自定义栈、堆
contextlib

类的内置方法

1
2
__str__ print(obj)的时候执行
__repr__ 没有str找repr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

@implements_bool
class LocalProxy(object):

__slots__ = ('__local', '__dict__', '__name__', '__wrapped__')

def __init__(self, local, name=None):
object.__setattr__(self, '_LocalProxy__local', local)
object.__setattr__(self, '__name__', name)
if callable(local) and not hasattr(local, '__release_local__'):
# "local" is a callable that is not an instance of Local or
# LocalManager: mark it as a wrapped function.
object.__setattr__(self, '__wrapped__', local)

def _get_current_object(self):
"""Return the current object. This is useful if you want the real
object behind the proxy at a time for performance reasons or because
you want to pass the object into a different context.
"""
if not hasattr(self.__local, '__release_local__'):
return self.__local()
try:
return getattr(self.__local, self.__name__)
except AttributeError:
raise RuntimeError('no object bound to %s' % self.__name__)

@property
def __dict__(self):
try:
return self._get_current_object().__dict__
except RuntimeError:
raise AttributeError('__dict__')

def __repr__(self):
try:
obj = self._get_current_object()
except RuntimeError:
return '<%s unbound>' % self.__class__.__name__
return repr(obj)

def __bool__(self):
try:
return bool(self._get_current_object())
except RuntimeError:
return False

def __unicode__(self):
try:
return unicode(self._get_current_object()) # noqa
except RuntimeError:
return repr(self)

def __dir__(self):
try:
return dir(self._get_current_object())
except RuntimeError:
return []

def __getattr__(self, name):
if name == '__members__':
return dir(self._get_current_object())
return getattr(self._get_current_object(), name)

def __setitem__(self, key, value):
self._get_current_object()[key] = value

def __delitem__(self, key):
del self._get_current_object()[key]

if PY2:
__getslice__ = lambda x, i, j: x._get_current_object()[i:j]

def __setslice__(self, i, j, seq):
self._get_current_object()[i:j] = seq

def __delslice__(self, i, j):
del self._get_current_object()[i:j]

__setattr__ = lambda x, n, v: setattr(x._get_current_object(), n, v)
__delattr__ = lambda x, n: delattr(x._get_current_object(), n)
__str__ = lambda x: str(x._get_current_object())
__lt__ = lambda x, o: x._get_current_object() < o
__le__ = lambda x, o: x._get_current_object() <= o
__eq__ = lambda x, o: x._get_current_object() == o
__ne__ = lambda x, o: x._get_current_object() != o
__gt__ = lambda x, o: x._get_current_object() > o
__ge__ = lambda x, o: x._get_current_object() >= o
__cmp__ = lambda x, o: cmp(x._get_current_object(), o) # noqa
__hash__ = lambda x: hash(x._get_current_object())
__call__ = lambda x, *a, **kw: x._get_current_object()(*a, **kw)
__len__ = lambda x: len(x._get_current_object())
__getitem__ = lambda x, i: x._get_current_object()[i]
__iter__ = lambda x: iter(x._get_current_object())
__contains__ = lambda x, i: i in x._get_current_object()
__add__ = lambda x, o: x._get_current_object() + o
__sub__ = lambda x, o: x._get_current_object() - o
__mul__ = lambda x, o: x._get_current_object() * o
__floordiv__ = lambda x, o: x._get_current_object() // o
__mod__ = lambda x, o: x._get_current_object() % o
__divmod__ = lambda x, o: x._get_current_object().__divmod__(o)
__pow__ = lambda x, o: x._get_current_object() ** o
__lshift__ = lambda x, o: x._get_current_object() << o
__rshift__ = lambda x, o: x._get_current_object() >> o
__and__ = lambda x, o: x._get_current_object() & o
__xor__ = lambda x, o: x._get_current_object() ^ o
__or__ = lambda x, o: x._get_current_object() | o
__div__ = lambda x, o: x._get_current_object().__div__(o)
__truediv__ = lambda x, o: x._get_current_object().__truediv__(o)
__neg__ = lambda x: -(x._get_current_object())
__pos__ = lambda x: +(x._get_current_object())
__abs__ = lambda x: abs(x._get_current_object())
__invert__ = lambda x: ~(x._get_current_object())
__complex__ = lambda x: complex(x._get_current_object())
__int__ = lambda x: int(x._get_current_object())
__long__ = lambda x: long(x._get_current_object()) # noqa
__float__ = lambda x: float(x._get_current_object())
__oct__ = lambda x: oct(x._get_current_object())
__hex__ = lambda x: hex(x._get_current_object())
__index__ = lambda x: x._get_current_object().__index__()
__coerce__ = lambda x, o: x._get_current_object().__coerce__(x, o)
__enter__ = lambda x: x._get_current_object().__enter__()
__exit__ = lambda x, *a, **kw: x._get_current_object().__exit__(*a, **kw)
__radd__ = lambda x, o: o + x._get_current_object()
__rsub__ = lambda x, o: o - x._get_current_object()
__rmul__ = lambda x, o: o * x._get_current_object()
__rdiv__ = lambda x, o: o / x._get_current_object()
if PY2:
__rtruediv__ = lambda x, o: x._get_current_object().__rtruediv__(o)
else:
__rtruediv__ = __rdiv__
__rfloordiv__ = lambda x, o: o // x._get_current_object()
__rmod__ = lambda x, o: o % x._get_current_object()
__rdivmod__ = lambda x, o: x._get_current_object().__rdivmod__(o)
__copy__ = lambda x: copy.copy(x._get_current_object())
__deepcopy__ = lambda x, memo: copy.deepcopy(x._get_current_object(), memo)