简体   繁体   中英

How to extend class method

Both SubClassA and SubClassB are the sub-classes of Base class (both inherit from same Base class). Since getInfo() method is declared within Base() class it (this method) is shared between both A and B sub-classes. When getInfo() method is called it returns the value of self.attr variable (shared among A and B sub-classes). 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. Likewise if instanceB is used: instanceB.getInfo() self.attrB is returned in addition to returning self.attr . How Base() class's method getInfo() can be extended so it is "customized" for both sub-classes A and 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. If desired, use super (as you are in your constructors) to get the result of the base class getInfo() and incorporate it as desired.

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. 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 .

You mentioned a need to call Base.method in your Derived object. That's where super comes in. super(Derived, self).method() will find and call Base.method on self . 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.

Note that the super(Base, self).__init__() line is not necessary; 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 .

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.

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

You can get the original function with the func attribute: ClassName.function_name = decorator(ClassName.function_name.__func__) .

from How can one attach a decorator to a function "after the fact" in python? (Martijn Pieters answering a question in the function/decorator domain)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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