我们具有以下类结构:
class NamePrinter():
def phone():
print(self.name)
def email():
print(self.name)
class PhoneCaller(NamePrinter):
def __init__(self, name, number, mail):
self.name = name
self.number = number
self.mail = mail
def phone(self):
# here, NamePrinter.phone() should be executed
compose_number(self.number)
def email(self):
# here, NamePrinter.email() should be executed
compose_mail(self.mail)
我希望在调用
NamePrinter.phone()
时执行PhoneCaller.phone()
,而不必在PhoneCaller中提及super.phone()
。这个想法是,为了执行PhoneCaller.phone时执行NamePrinter的行为而对PhoneCaller进行的唯一修改是,PhoneCaller继承自父对象,仅此而已。特别是,无需修改任何单独的PhoneCaller方法。
简单地说:
PhoneCaller继承自NamePrinter =>在编写号码之前打印名称
PhoneCaller不能从NamePrinter继承=>不打印名称
无需搞乱PhoneCaller.phone
这可能吗?
最佳答案
是的,至少有可能使用元类:
def new_attr(attr_name, attr):
name_printer_attr = getattr(NamePrinter, attr_name)
def _new_attr(self, *args, **kwargs):
name_printer_attr(self)
return attr(self, *args, **kwargs)
return _new_attr
class Meta(type):
def __new__(cls, name, bases, attrs):
if name == 'NamePrinter':
cls.attrs = attrs
else:
for attr_name, attr in attrs.items():
if callable(attr) and attr_name in cls.attrs:
attrs[attr_name] = new_attr(attr_name, attr)
return type.__new__(cls, name, bases, attrs)
class NamePrinter(metaclass=Meta):
def phone(self):
print('NamePrinter phone')
class PhoneCaller1:
def phone(self):
print('PhoneCaller1 phone')
class PhoneCaller2(NamePrinter):
def phone(self):
print('PhoneCaller2 phone')
p1 = PhoneCaller1()
p1.phone() # will print only "PhoneCaller1 phone"
p2 = PhoneCaller2()
p2.phone() # will print "NamePrinter phone" and "PhoneCaller2 phone" on next line