Python 魔术方法小结
Posted tomyyyyy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python 魔术方法小结相关的知识,希望对你有一定的参考价值。
Python 魔术方法小结
_ _ init __
实例化对象时调用
class Foo:
def init(self,name):
self.name = name
f = Foo(‘CharmNight‘) # 这时候就调用init方法
_ _ new__
创建类对象时调用
_ _ new__ ()方法始终都是 类的静态方法,即使没有被加上静态方法装饰器
class Foo:
def new(cls,*args,**kwargs):
return super().new(cls)
def init(self):
pass
f = Foo()
__new()__ 方法创建对象,在init()方法之前被调用,返回一个self对象,并将该对象传给init()的第一个参数。一般不需要复写new()方法,如果有需求:例如 单例模式可以通过重写new方法 或者在类创建时进行一些修改
单例模式
当然单例模式不止这一种写法,有很多方法都可以实现单例
# 通过__new__()方法实现单例模式
class Foo:
_instance = None
def __new__(cls, *args, **kwargs):
if not hasattr(Foo,‘_instance‘):
cls._instance = super().__new__(cls)
return cls._instance
__ call__
Python中的函数是一级对象。这意味着Python中的函数的引用可以作为输入传递到其他的函数/方法中,并在其中被执行。
而Python中类的实例(对象)可以被当做函数对待。也就是说,我们可以将它们作为输入传递到其他的函数/方法中并调用他们,正如我们调用一个正常的函数那样。而类中__call()__
函数的意义正在于此。为了将一个类实例当做函数调用,我们需要在类中实现__call()__
方法。也就是我们要在类中实现如下方法:def __call__(self, [args...])
。这个方法接受一定数量的变量作为输入。__call()__
的作用是使实例能够像函数一样被调用,同时不影响实例本身的生命周期(__call()__
不影响一个实例的构造和析构)。但是__call()__
可以用来改变实例的内部成员的值
说人话就是__call__
方法就是 让对象加括号 执行call里的内容。
class Foo:
def __init__(self, name):
self.name = name
def __call__(self, *args, **kwargs):
self.name = self.name.upper()
f = Foo(‘Charm_Night‘)
f()
print(f.name)
__ getattr__
拦截点号运算。当对未定义的属性名称和实例进行点号运算时,就会用属性名作为字符串调用这个方法。如果继承树可以找到该属性,则不调用此方法
class Foo():
def __init__(self, item):
self.item = item
def __getattr__(self, item):
print(‘Run getattr‘)
return item
f = Foo([1,2,3])
print(f.name)
Run getattr
name
哈?说没看懂什么时候调用? 简单说就是当调用该属性却没有找到时,就会执行_ _ getattr _ _方法
如果属性查找(attribute lookup)在实例以及对应的类中(通过__dict__)失败, 那么会调用到类的__getattr__函数, 如果没有定义这个函数,那么抛出AttributeError异常。由此可见,__getattr__一定是作用于属性查找的最后一步,兜底
_ _ getattr _ _ 使得实现adapter wrapper模式非常容易,我们都知道“组合优于继承”,_ _ getattr __实现的adapter就是以组合的形式。
eg:
_ _ getattr _ _ 使得实现adapter wrapper模式非常容易,我们都知道“组合优于继承”,_ _ getattr __实现的adapter就是以组合的形式。
class adaptee(object):
def foo(self):
print( ‘foo in adaptee‘)
def bar(self):
print (‘bar in adaptee‘)
class adapter(object):
def __init__(self):
self.adaptee = adaptee()
def foo(self):
print(‘foo in adapter‘)
self.adaptee.foo()
def __getattr__(self, name):
print(‘run‘)
return getattr(self.adaptee, name)
if __name__ == ‘__main__‘:
a = adapter()
a.foo()
a.bar()
foo in adapter
foo in adaptee
bar in adaptee
_ _ getattribute__
_ _ getattribute__是访问属性的方法,我们可以通过方法重写来扩展方法的功能。
对于python来说,属性或者函数都可以被理解成一个属性,且可以通过_ _ getattribute__获取。
当获取属性时,直接return object._ getattribute_(self,item) 或者使用 super(). _ _ getattribute _ _(item)
class Foo:
def __init__(self):
self.name = ‘Night‘
def __getattribute__(self, item):
print(‘Run getattribute‘)
if item is ‘func‘:
return super().__getattribute__(‘func‘)
elif item is ‘name‘:
return super().__getattribute__(‘name‘)
else:
return super().__getattribute__(‘demo‘)
def demo(self):
print(‘Run demo‘)
def func(self):
print(‘Run func‘)
f = Foo()
print(f.name)
f.func()
f.a()
以上是关于Python 魔术方法小结的主要内容,如果未能解决你的问题,请参考以下文章
PHP中的抽象类与抽象方法/静态属性和静态方法/PHP中的单利模式(单态模式)/串行化与反串行化(序列化与反序列化)/约束类型/魔术方法小结