Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apply a method to an object of another class

Tags:

python

Given two non-related classes A and B, how to call A.method with an object of B as self?

class A:
    def __init__(self, x):
        self.x = x

    def print_x(self):
        print self.x

class B:
    def __init__(self, x):
        self.x = x

a = A('spam')
b = B('eggs')

a.print_x() #<-- spam
<magic>(A.print_x, b) #<-- 'eggs'
like image 557
georg Avatar asked Mar 12 '12 08:03

georg


People also ask

How do you call a method from another class without creating an object?

We can call a static method by using the ClassName. methodName. The best example of the static method is the main() method. It is called without creating the object.

Can you call a method from another class in Java?

We can call the private method of a class from another class in Java (which are defined using the private access modifier in Java). We can do this by changing the runtime behavior of the class by using some predefined methods of Java. For accessing private method of different class we will use Reflection API.


1 Answers

In Python 3.x you can simply do what you want:

A.print_x(b) #<-- 'eggs'

If you only have an instance of 'A', then get the class first:

a.__class__.print_x(b) #<-- 'eggs'

In Python 2.x (which the OP uses) this doesn't work, as noted by the OP and explained by Amber in the comments:

This is a difference between Python 2.x and Python 3.x - methods in 3.x don't enforce being passed the same class.

More details (OP edit)

In python 2, A.print_x returns an "unbound method", which cannot be directly applied to other classes' objects:

When an unbound user-defined method object is called, the underlying function (im_func) is called, with the restriction that the first argument must be an instance of the proper class (im_class) or of a derived class thereof. >> http://docs.python.org/reference/datamodel.html

To work around this restriction, we first have to obtain a "raw" function from a method, via im_func or __func__ (2.6+), which then can be called passing an object. This works on both classes and instances:

# python 2.5-
A.print_x.im_func(b)    
a.print_x.im_func(b)

# python 2.6+
A.print_x.__func__(b)   
a.print_x.__func__(b)

In python 3 there's no such thing anymore as unbound method.

Unbound methods are gone for good. ClassObject.method returns an ordinary function object, instance.method still returns a bound method object. >> http://www.python.org/getit/releases/3.0/NEWS.txt

Hence, in python 3, A.print_x is just a function, and can be called right away and a.print_x still has to be unbounded:

# python 3.0+
A.print_x(b)
a.print_x.__func__(b)
like image 73
Reinstate Monica Avatar answered Sep 25 '22 04:09

Reinstate Monica