跳转至

03 魔法函数

魔法函数

python沙箱逃逸还是离不开继承关系和子父类关系,在查看和使用类的继承,魔法函数起到了不可比拟的作用。

先看看几个常用的魔法函数

__class__
返回调用的类型
>>> class A():
>>>     pass
...
>>> a = A()
>>> print(a.__class__)  # <class '__main__.A'>
<class '__main__.A'>

__mro__
查看类继承的所有父类直到object
>>> class A(object):
...     pass
...
>>> class B(A):
...     pass
...
>>> class C(A):
...     pass
...
>>> class D(B,C):
...     pass
...
>>> print(D.__mro__)  # (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
__subclasses__
获取类的所有子类
>>> class A(object):
...     pass
...
>>> class B(A):
...     pass
...
>>> class C(A):
...     pass
...
>>> print(A.__subclasses__())  # [<class '__main__.B'>, <class '__main__.C'>]
[<class '__main__.B'>, <class '__main__.C'>]
__bases__
返回所有直接父类组成的元组
>>> class A(object):
...     pass
...
>>> class B(A):
...     pass
...
>>> print(B.__bases__)  # (<class '__main__.A'>,)  不返回object类
(<class '__main__.A'>,)
__init__
类实例创建之后调用, 对当前对象的实例的一些初始化
>>> class A:
...     def __init__(self):
...         print("ok")
...
>>> a = A()  # 输出ok
ok
__globals__
能够返回函数所在模块命名空间的所有变量
>>> class A(object):
...     def __init__(self, a, b):
...         self.a = a
...         self.b = b
...
>>> a = A(1, 2)
>>> a.__init__.__globals__
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'A': <class '__main__.A'>, 'a': <__main__.A object at 0x7f452cdb5040>}
__getattribute__
当类被调用的时候无条件进入此函数
__getattr__
对象中不存在的属性时调用
>>> class A:
>>>     def __init__(self):
>>>         self.name = "Bob"
>>>     def __getattribute__(self, item):
>>>         print("ok")
>>>     def __getattr__(self):
>>>         print('getattr')
...
>>> a = A()
>>> a.name  # ok, 这时候不管调用什么属性都会返回ok,相当于拦截了属性调用。
ok
>>> a.age   # getattr  调用不存在的属性会执行,相当于处理了AttributeError。
getattr