I'm trying to call an external function via a class variable. The following is a simplification of my real code:
def func(arg):
print(arg)
class MyClass(object):
func_ref = None
@classmethod
def setUpClass(cls):
#MyClass.func_ref = func
cls.func_ref = func
@staticmethod
def func_override(arg):
print("override printing arg...")
MyClass.func_ref(arg)
if __name__ == "__main__":
print(type(func))
print(type(MyClass.func_ref))
MyClass.setUpClass()
print(type(MyClass.func_ref))
MyClass.func_override("hello!")
The above code produces the following output:
[~]$ python tmp.py
<type 'function'>
<type 'NoneType'>
<type 'instancemethod'>
override printing arg...
Traceback (most recent call last):
File "tmp.py", line 20, in <module>
MyClass.func_override("hello!")
TypeError: func_override() takes exactly 2 arguments (1 given)
The situation seems to be unchanged if I use MyClass
in place of cls
within the classmethod setUpClass()
.
I would expect the type of MyClass.func_ref
to be function
after the assignment in setUpClass()
which explains the TypeError
I get when I try to call it. Why is the type of func_ref
being changed to instancemethod
when the value I assigned to it is of type function
?
This only seems to be an issue in Python 2. Python 3 behaves as I would expect.
How do I get calls to the static method MyClass.func_override()
to call func()
?
UPDATE
I was able to get the above to work by applying the following patch:
@@ -14,7 +14,7 @@ class MyClass(object):
def func_override(arg):
print("override printing arg...")
func(arg)
- MyClass.func_ref.__func__(arg)
+ MyClass.func_ref(arg)
if __name__ == "__main__":
print(type(func))
While the above works, its not at all clear to me why I needed to do this. I still don't understand why the type of func_ref
ends up an instancemethod
when I assigned to it a value of type function
.