我们具有以下类结构:

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

09-04 07:24