简体   繁体   中英

How can I reuse another classes' method without inheritance in Python 2?

Two of my classes need to have the same method, but they are not related by inheritance.

The following works in Python 3:

class A(object):
    def __init__(self):
        self.x = 'A'

    def printmyx(self):
        print(self.x)

class B(object):
    def __init__(self):
        self.x = 'B'

    printmyx = A.printmyx

a = A()
b = B()

a.printmyx()
b.printmyx()

and prints

A
B

However, in Python 2 I'm getting

Traceback (most recent call last):
  File "py2test.py", line 18, in <module>
    b.printmyx()
TypeError: unbound method printmyx() must be called with A instance as first argument (got nothing instead)

I think the problem is that in Python 3 printmyx is just a regular function while in Python 2 it's an unbound method.

How to make the code work in Python 2?

edit

In my real code, A and B inherit from different parent classes. They need to share one helper method but have no other relation to each other.

Bear in mind that Python does support multiple inheritance, so it's very possible to define a mixin class and have both A and B inherit from it without disturbing the main inheritance hierarchy. I understand you're saying the classes have little in common - but they do both have a variable called x and a method to print it - and to me at least, that's enough in common to consider using inheritance.

But that said, another way to do this is using a class decorator to add the common method:

def add_printmyx(original_class):
    def printmyx(self):
        print (self.x)
    original_class.printmyx = printmyx
    return original_class

@add_printmyx
class B(object):
    def __init__(self):
        self.x = 'B'

b = B()
b.printmyx()

The class decorator takes the original class and adds (or replaces) a printmyx method that prints the contents of x.

Apparently, in Python 2 the original function an unbound method was created from is stored in the im_func attribute. 1

To make the code work in Python 2 like it does in Python 3, use

printmyx = A.printmyx.im_func

in B 's body.

1 Described in the The standard type hierarchy section of the Python 2 Data Model documentation.

Why is inheritance not allowed? This is the perfect use case for inheritance.

class Common(object):
    def printmyx(self):
        print(self.x)

class A(Common):
    def __init__(self):
        self.x = 'A'

class B(Common):
    def __init__(self):
        self.x = 'B'

a = A()
b = B()

a.printmyx()
b.printmyx()

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