简体   繁体   English

如何扩展 class 方法

[英]How to extend class method

Both SubClassA and SubClassB are the sub-classes of Base class (both inherit from same Base class). SubClassASubClassB都是Base class 的子类(都继承自同一个Base类)。 Since getInfo() method is declared within Base() class it (this method) is shared between both A and B sub-classes.由于getInfo()方法是在Base() class 中声明的,因此它(此方法)在 A 和 B 子类之间共享。 When getInfo() method is called it returns the value of self.attr variable (shared among A and B sub-classes).getInfo()方法时,它返回self.attr变量的值(在 A 和 B 子类之间共享)。 Now I want to "extend" this method.现在我想“扩展”这个方法。 So when it is called via subClassA instance using instanceA.getInfo() in addition to self.attr it would return self.attrA as well.因此,当除了self.attr之外还使用instanceA.getInfo()通过 subClassA 实例调用它时,它也会返回self.attrA Likewise if instanceB is used: instanceB.getInfo() self.attrB is returned in addition to returning self.attr .同样,如果使用 instanceB:除了返回self.attr之外,还返回instanceB.getInfo() self.attrB How Base() class's method getInfo() can be extended so it is "customized" for both sub-classes A and B?如何扩展Base()类的方法getInfo()以便为子类 A 和 B 都“定制”它?

class Base(object):
    def __init__(self):
        super(Base, self).__init__()
        self.attr='Attr'

    def getInfo(self):
        info=self.getAttr()
        return info
    def getAttr(self):
        return self.attr

class SubClassA(Base):
    def __init__(self):
        super(SubClassA, self).__init__()  
        self.attrA='attrA'      
    def getAttrA(self):
        return self.attrA

class SubClassB(Base):
    def __init__(self):
        super(SubClassB, self).__init__()  
        self.attrB='attrB'      
    def getAttrB(self):
        return self.attrB

instanceA=SubClassA()
instanceB=SubClassB()
print instanceA.getInfo()
print instanceB.getInfo()

Simply define the getInfo method in the subclasses. 只需在子类中定义getInfo方法即可。 If desired, use super (as you are in your constructors) to get the result of the base class getInfo() and incorporate it as desired. 如果需要,使用super (就像在构造函数中一样)来获取基类getInfo()并根据需要合并它。

To elaborate: when given an instance c of some class C , and asked to look up an attribute c.attr , Python looks for the attribute in a sequence of places. 详细说明:当给定某个类C的实例c并要求查找属性c.attr ,Python会在一系列位置中查找该属性。 In particular, it will look in derived classes before base classes. 特别是,它将在基类之前查找派生类。 Thus the following code 这样下面的代码

class Base(object):
    def method(self):
        return "I'm a base object!"

class Derived(Base):
    def method(self):
        return "I'm a derived object!"

obj = Derived()
print obj.method()

will print "I'm a derived object!", because Python looks for method in Derived , finds it, and never checks in Base . 将打印“我是派生对象!”,因为Python在Derived中查找method ,找到它,并且从不在Base检查。

You mentioned a need to call Base.method in your Derived object. 您提到需要在Derived对象中调用Base.method That's where super comes in. super(Derived, self).method() will find and call Base.method on self . 这就是super进来的地方。 super(Derived, self).method()会在self Base.method找到并调用Base.method You are already doing that in your constructors. 您已经在构造函数中执行此操作。

For example: 例如:

class Computer(object):
    def boot_message(self):
        return 'I am a computer'

class AppleComputer(Computer):
    def boot_message(self):
        return super(AppleComputer, self).boot_message() + ' with a really shiny logo'

We avoid duplicating the effort in Computer.boot_message by taking its result and modifying it as necessary. 我们通过获取其结果并根据需要进行修改来避免在Computer.boot_message重复工作。

Note that the super(Base, self).__init__() line is not necessary; 注意, super(Base, self).__init__()行不是必需的; in general such calls are only desirable if the base class __init__() does work that the derived class __init__() wants to accomplish without code duplication, which is not the case for object . 通常,只有当基类__init__()确实有效时,派生类__init__()才能在没有代码重复的情况下完成这种调用,而object不是这种情况。

An additional option is that you can return both attributes:另一个选项是您可以返回两个属性:

return self.attr, self.attrA

Also, another approach in addition to .nethreeseven's is you can extend the attr data itself with your attrA data, such as in a list or adding to a string, and return that.此外,除了 .nethreeseven 之外,另一种方法是您可以使用 attrA 数据扩展 attr 数据本身,例如在列表中或添加到字符串中,然后返回它。

Or you can call both methods you have recursively or with a decorator, which is possible as follows.或者您可以递归地或使用装饰器调用您拥有的两种方法,这可能如下所示。 Access (and thus redefine) the definition of a class directly直接访问(并重新定义)class 的定义

You can get the original function with the func attribute: ClassName.function_name = decorator(ClassName.function_name.__func__) .您可以获得带有func属性的原始 function: ClassName.function_name = decorator(ClassName.function_name.__func__)

from How can one attach a decorator to a function "after the fact" in python?来自如何在 python 中“事后”将装饰器附加到 function? (Martijn Pieters answering a question in the function/decorator domain) (Martijn Pieters 在功能/装饰器领域回答问题)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM