假设我有一个包含多个函数的类。
class Person:
def __init__(self): pass
def say(self, speech): pass
def walk(self, destination): pass
def jump(self): pass
Run Code Online (Sandbox Code Playgroud)
当用户实例化一个 Person 时,我希望他们能够调用该类的任何方法。如果请求的方法不存在(例如Person.dance()
),则应调用默认函数。
我想这可以通过理论上的魔法方法来完成 -
class Person:
def __init__(self): pass
def say(self, speech): pass
def walk(self, destination): pass
def jump(self): pass
def sleep(self): print("Zzz")
def __method__(self, func):
if func.__name__ not in ['say','walk','jump']:
return self.sleep
else
return func
billy = Person()
billy.dance()
>> "Zzz"
Run Code Online (Sandbox Code Playgroud)
然而,我不知道有这样的神奇方法。
有没有办法使类中不存在的方法重定向到另一个类?
重要的是,最终用户无需执行任何操作 - 从他们的角度来看,它应该可以正常工作。
捕获未定义属性的标准方法是使用__getattr__
:
# But see the end of the answer for an afterthought
def __getattr__(self, attr):
return self.sleep
Run Code Online (Sandbox Code Playgroud)
Python 不区分“常规”属性和方法;方法调用从普通的属性查找开始,其结果恰好是可调用的。那是,
billy.run()
Run Code Online (Sandbox Code Playgroud)
是相同的
f = billy.run
f()
Run Code Online (Sandbox Code Playgroud)
这意味着任何__getattr__
未定义的属性都会被调用;没有办法在查找时判断结果是否会被调用。
但是,如果您只想为通用方法定义“别名”,则可以在class
语句后使用循环来实现。
class Person:
def __init__(self): pass
def say(self, speech): pass
def walk(self, destination): pass
def jump(self): pass
def do_all(self): pass
for alias in ["something", "something_else", "other"]:
setattr(Person, alias, Person.do_all)
Run Code Online (Sandbox Code Playgroud)
您还可以在语句中进行硬编码分配class
,但如果正如您提到的那样,有数百个这样的情况,那么这将很麻烦:
class Person:
def do_all(self): pass
something = do_all
something_else = do_all
Run Code Online (Sandbox Code Playgroud)
(我没有尝试使用exec
循环自动执行此类分配;这可能是可能的,但不建议这样做。)
您还可以在 的定义中嵌入别名列表__getattr__
,想想看:
def __getattr__(self, attr):
if attr in ["something", "something_else", "other"]:
return self.sleep
else:
raise AttributeError(f"type object 'Person' has no attribute '{attr}'")
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2096 次 |
最近记录: |