Various errors in code that tries to call classmethods [closed] - python

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I have this code:
class SomeClass:
#classmethod
def func1(cls,arg1):
#---Do Something---
#classmethod
def func2(cls,arg1):
#---Do Something---
# A 'function map' that has function name as its keys and the above function
# objects as values
func_map={'func1':func1,'func2':func2}
#classmethod
def func3(cls,arg1):
# following is a dict(created by reading a config file) that
# contains func names as keys and boolean as values that tells
# the program whether or not to run that function
global funcList
for func in funcList:
if funcList[func]==True:
cls.func_map[func](arg1) #TROUBLING PART!!!
if _name__='main'
SomeClass.func3('Argumentus-Primus')
When I run this I keep getting the error:
Exception TypeError: "'classmethod' object is not callable"
I am unable to figure out what is wrong with this and would appreciate your help.

You can't create references to classmethods until the class has been defined. You'll have to move it out of the class definition. However using a global function map to decide what gets run is really awkward. If you described what you are trying to do with this, we could probably suggest a better solution.
class SomeClass(object):
#classmethod
def func1(cls, arg1):
print("Called func1({})".format(arg1))
#classmethod
def func2(cls, arg1):
print("Call func2({})".format(arg1))
#classmethod
def func3(cls, arg1):
for fnName,do in funcList.iteritems():
if do:
try:
cls.func_map[fnName](arg1)
except KeyError:
print("Don't know function '{}'".format(fnName))
# can't create function map until class has been created
SomeClass.func_map = {
'func1': SomeClass.func1,
'func2': SomeClass.func2
}
if __name__=='__main__':
funcList = {'func1':True, 'func2':False}
SomeClass.func3('Argumentus-Primus')

I discovered something tonight that will be helpful here: We can unwrap magic staticmethod and classmethod objects via: getattr(func, '__func__')
How did I find this information? Using JetBrains' PyCharm (I don't know about other Python IDEs), I viewed the source code for #staticmethod and #classmethod. Both classes define the attribute __func__.
"The rest is left as an exercise for the reader."

All other answers suggest to add some code outside the class SomeClass definition. It may be ok in some cases, but in my case it was very inconvenient. I really wanted to keep the func_map inside the class.
I suggest the following approach. Use not a class variable, but one more classmethod:
class SomeClass:
# ...
#classmethod
def get_func_map(cls):
return {'func1': cls.func1, 'func2': cls.func2}
#classmethod
def func3(cls, arg1):
# .....
cls.get_func_map()[func_name](arg1)
Of course you should modify this code so that a new dictionary not be constructed each time you call the get_func_map method. It's easy, I did not do myself it to keep the example small and clear.
Tested on python 3.6

Add self as an argument for each method within the class.
Also
if _name__='main'
SomeClass.func3('Argumentus-Primus')
should look like this:
if __name__=='__main__':
SomeClass.func3('Argumentus-Primus')
and should not be within the body of the class.

You may need to try a static method.
#staticmethod
def function():...
Static methods do not pass the class as an implicit first argument.

Here's a bad way to do it:
def func3(cls,arg1):
global funcList
for func in funcList:
if funcList[func]==True:
eval(f'SomeClass.{func}')(arg1)
Only works if func is the name of the function. That being said, do not use this method, because you're taking user input. It would be very easy to inject nasty code in the call. That being said, this does work.

Related

Proper way to define function in a class that does not use self value

I am new to opp programming.I wanted to know what to do with a function that is inside the class but does not use self value
For example
class example:
def __init__(self,n):
self.number=n
def get_t(self,t):
return t*t
def main(self):
b=1
k=self.get_t(b)
From the example the function get_t has nothing to do with self value.
So I wanted to know where to place the function get_t or may be how to restructure the class.
Thank you for your consideration
What you're looking for are static methods. To declare a method static do it like this
#staticmethod
def foo():
pass
Nothing. Just let it be, Python won't complain about it and there's nothing fundamentally wrong about methods that doesn't use its instance. If your linter complains about it, you can shut up that warning. These kind of helper functions are often intended to be private methods that aren't intended to be used externally, you may want to prefix the name with underscore to indicate that.
Convert it into a free function. Python is an OOP language, but it's also a mixed paradigm language, unlike Java, for example, you can actually create a function outside of a class declaration. Pythonic code does not necessarily means putting everything into classes, and often a free function is perfectly suitable place for functions that doesn't involve a particular object instance.
def get_t(t):
return t*t
class example:
def main(self):
b=1
k=self.get_t(b)
If you want to be able to call it from the class by doing Example.get_t(blah) without having to have an instance, then you can either use the staticmethod or classmethod decorator. I suggest using classmethod which can do everything that staticmethod can do while the reverse isn't true and it's easier to make classmethod work correctly when you need to override it in a multi inheritance situation. staticmethod has a very tiny performance advantage, but you're microoptimizing if that's your concern.
class example:
#classmethod
def get_t(cls, t):
return t*t
def main(self):
b=1
k=self.get_t(b)
If get_t() is only being called from one method, you can put it as an inner function of that method:
class example:
def main(self):
def get_t(t):
return t * t
b=1
k=self.get_t(b)
With regards to naming, get_xxx is usually a code smell in python. The get_ prefix indicates that the method is likely a getter, and pythonic code usually don't use getters/setters, because the language supports property. What you have on here though, isn't actually a getter but rather a computation method, so it shouldn't be prefixed with get_. A better name might be calculate_t(t) or square(t).
Case 1: If self is there:-
class example:
def get_t(self,t):
return t*t
Then You can not access get_t function directly from class example like example.get_t(t=2) ,it will give you error. But you can access now by creating an object of class like q = example() and then q.get_t(t=2) , it will give you your desired result.
Case 2 : If self is not there:-
class example:
def get_t(t):
return t*t
Now You can directly access get_t function by class example like example.get_t(t=2) ,it will give you your desired result. But now you cannot use get_t function by creating object like q = example() then q.get_t(t=2) it will give you error.
Conclusion :- It all depends on your use case. But when you struck in this type of ambiguity use #staticmethod like given below:-
class example:
#staticmethod
def get_t(t):
return t*t
I hope it may help you.

How can I append/replace an implementation to a class method in Python?

Code first:
from abc import abstractmethod
class SomeInterfaceishClass():
#abstractmethod
#staticmethod
def foo(bar):
pass
class SomeClass(SomeInterfaceishClass):
#staticmethod
def foo(bar):
print("implementation here")
class EventHandler():
#staticmethod
#Multitasking.threaded
def foo(bar):
pass
I'm writing a frameworkish thingy where the end-user is forced to implement a few methods (only one here for simplicity). Therefore I have defined the SomeInterfaceishClass class with a abstract method. My problem is that I will not run the method from this class, instead, I'd like to run it from the EventHandler class. As you can see it has a decorator to make it run async and I think this is where the problem arises.
I know that I can call EventHandler.foo = getattr(self, 'foo') in the constructor of SomeInterfaceishClass, but when I do this the complete function will be overridden (loses it's decorator).
I'd like to keep the end-users code as clean as possible and therefore don't really want to add the decorator in SomeClass.
Is there any way to accomplish this? For example is there a way to add an implementation to a class method, rather than add a method to a class?
Just to be clear: I want to add it to the EventHandler class, not an instance of it.
Thank you all! :)

Multiple ways to define a class method in Python?

In Dive Into Python, Mark Pilgrim says that:
When defining your class methods, you must explicitly list self as the first argument for each method
He then gives a few examples of this in code:
def clear(self): self.data.clear()
def copy(self):
if self.__class__ is UserDict:
return UserDict(self.data)
import copy
return copy.copy(self)
While going through some Python code online, I came across the #classmethod decorator. An example of that is:
class Logger:
#classmethod
def debug(msg):
print "DEBUG: " + msg
(Notice that there is no self parameter in the debug function)
Is there any difference in defining class methods using self as the first parameter and using the #classmethod decorator? If not, is one way of defining class methods more commonly used/preferred over another?
#classmethod isn't the same as defining an instance method. Functions defined with #classmethod receive the class as the first argument, as opposed to an instance method which receives a specific instance. See the Python docs here for more information.
self is not and will never will be implicit.
"self will not become implicit.
Having self be explicit is a good thing. It makes the code clear by removing ambiguity about how a variable resolves. It also makes the difference between functions and methods small."
http://www.python.org/dev/peps/pep-3099/

Cannot call method unless its global from a class

Hi I am new to Disco and integrating existing code to it. Is Disco capable to call map/reduce function as a function within a class instead of global function? The following code might explain more clearly.
class Segmenter(object):
def map_fun(line, params):
....
def reduce_fun(iter, params):
....
def disco_mp(self):
job = Job().run(input=["raw://word_to_segment_......"],
map=map_fun,
reduce=reduce_fun)
...
The result of execution is
NameError: global name 'map_fun' is not defined
But if I change map_fun, reduce_fun into global function, it would work fine as expected.
However I still have to find a way to make it work as class functions, is there any way to
do it ?
Thanks,
Chandler
You need static method, you can do this with decorator:
class Segmenter(Job):
map = staticmethod(map_fun)
reduce = staticmethod(reduce_fun)
#staticmethod
def map_fun(line, params):
....
#staticmethod
def reduce_fun(iter, params):
....
def disco_mp(self):
job = self.run(input=["raw://word_to_segment_......"])
Note that you will not have access to self in both map_fun and reduce_fun, and this is why params exists. Also note that Job.run is now self.run and Segmenter extends Job.
It looks like you want to use self.map_fun and self.reduce_fun. Methods of objects can't be accessed by their bare names in Python; you have to use self. You will also need to provide a self argument to those methods. You should read the Python tutorial to familiarize yourself with the basics of classes and methods in Python.
(Also, why is the title of your question unrelated to the actual question?)

How to cast object in Python

I have two classes (let's call them Working and ReturnStatement) which I can't modify, but I want to extend both of them with logging. The trick is that the Working's method returns a ReturnStatement object, so the new MutantWorking object also returns ReturnStatement unless I can cast it to MutantReturnStatement. Saying with code:
# these classes can't be changed
class ReturnStatement(object):
def act(self):
print "I'm a ReturnStatement."
class Working(object):
def do(self):
print "I am Working."
return ReturnStatement()
# these classes should wrap the original ones
class MutantReturnStatement(ReturnStatement):
def act(self):
print "I'm wrapping ReturnStatement."
return ReturnStatement().act()
class MutantWorking(Working):
def do(self):
print "I am wrapping Working."
# !!! this is not working, I'd need that casting working !!!
return (MutantReturnStatement) Working().do()
rs = MutantWorking().do() #I can use MutantWorking just like Working
print "--" # just to separate output
rs.act() #this must be MutantReturnState.act(), I need the overloaded method
The expected result:
I am wrapping Working.
I am Working.
--
I'm wrapping ReturnStatement.
I'm a ReturnStatement.
Is it possible to solve the problem? I'm also curious if the problem can be solved in PHP, too. Unless I get a working solution I can't accept the answer, so please write working code to get accepted.
There is no casting as the other answers already explained. You can make subclasses or make modified new types with the extra functionality using decorators.
Here's a complete example (credit to How to make a chain of function decorators?). You do not need to modify your original classes. In my example the original class is called Working.
# decorator for logging
def logging(func):
def wrapper(*args, **kwargs):
print func.__name__, args, kwargs
res = func(*args, **kwargs)
return res
return wrapper
# this is some example class you do not want to/can not modify
class Working:
def Do(c):
print("I am working")
def pr(c,printit): # other example method
print(printit)
def bla(c): # other example method
c.pr("saybla")
# this is how to make a new class with some methods logged:
class MutantWorking(Working):
pr=logging(Working.pr)
bla=logging(Working.bla)
Do=logging(Working.Do)
h=MutantWorking()
h.bla()
h.pr("Working")
h.Do()
this will print
h.bla()
bla (<__main__.MutantWorking instance at 0xb776b78c>,) {}
pr (<__main__.MutantWorking instance at 0xb776b78c>, 'saybla') {}
saybla
pr (<__main__.MutantWorking instance at 0xb776b78c>, 'Working') {}
Working
Do (<__main__.MutantWorking instance at 0xb776b78c>,) {}
I am working
In addition, I would like to understand why you can not modify a class. Did you try? Because, as an alternative to making a subclass, if you feel dynamic you can almost always modify an old class in place:
Working.Do=logging(Working.Do)
ReturnStatement.Act=logging(ReturnStatement.Act)
Update: Apply logging to all methods of a class
As you now specifically asked for this. You can loop over all members and apply logging to them all. But you need to define a rule for what kind of members to modify. The example below excludes any method with __ in its name .
import types
def hasmethod(obj, name):
return hasattr(obj, name) and type(getattr(obj, name)) == types.MethodType
def loggify(theclass):
for x in filter(lambda x:"__" not in x, dir(theclass)):
if hasmethod(theclass,x):
print(x)
setattr(theclass,x,logging(getattr(theclass,x)))
return theclass
With this all you have to do to make a new logged version of a class is:
#loggify
class loggedWorker(Working): pass
Or modify an existing class in place:
loggify(Working)
There is no "casting" in Python.
Any subclass of a class is considered an instance of its parents. Desired behavior can be achieved by proper calling the superclass methods, and by overriding class attributes.
update: with the advent of static type checking, there is "type casting" - check bellow.
What you can do on your example, is to have to have a subclass initializer that receives the superclass and copies its relevant attributes - so, your MutantReturnstatement could be written thus:
class MutantReturnStatement(ReturnStatement):
def __init__(self, previous_object=None):
if previous_object:
self.attribute = previous_object.attribute
# repeat for relevant attributes
def act(self):
print "I'm wrapping ReturnStatement."
return ReturnStatement().act()
And then change your MutantWorking class to:
class MutantWorking(Working):
def do(self):
print "I am wrapping Working."
return MutantReturnStatement(Working().do())
There are Pythonic ways for not having a lot of self.attr = other.attr lines on the __init__method if there are lots (like, more than 3 :-) ) attributes you want to copy -
the laziest of which wiuld be simply to copy the other instance's __dict__ attribute.
Alternatively, if you know what you are doing, you could also simply change the __class__ attribute of your target object to the desired class - but that can be misleading and carry you to subtle errors (the __init__ method of the subclass would not be called, would not work on non-python defined classes, and other possible problems), I don't recomment this approach - this is not "casting", it is use of introspection to bruteforce an object change and is only included for keeping the answer complete:
class MutantWorking(Working):
def do(self):
print "I am wrapping Working."
result = Working.do(self)
result.__class__ = MutantReturnStatement
return result
Again - this should work, but don't do it - use the former method.
By the way, I am not too experienced with other OO languages, that allow casting - but is casting to a subclass even allowed in any language? Does it make sense? I think casting s only allowed to parentclasses.
update: When one works with type hinting and static analysis in the ways describd in PEP 484, sometimes the static analysis tool can't figure out what is going on. So, there is the typing.cast call: it does absolutely nothing in runtime, just return the same object that was passed to it, but the tools then "learn" that the returned object is of the passed type, and won't complain about it. It will remove typing errors in the helper tool, but I can't emphasise enough it does not have any effect in runtime:
In [18]: from typing import cast
In [19]: cast(int, 3.4)
Out[19]: 3.4
No direct way.
You may define MutantReturnStatement's init like this:
def __init__(self, retStatement):
self.retStatement = retStatement
and then use it like this:
class MutantWorking(Working):
def do(self):
print "I am wrapping Working."
# !!! this is not working, I'd need that casting working !!!
return MutantReturnStatement(Working().do())
And you should get rid from inheriting ReturnStatement in your wrapper, like this
class MutantReturnStatement(object):
def act(self):
print "I'm wrapping ReturnStatement."
return self.retStatement.act()
You don't need casting here. You just need
class MutantWorking(Working):
def do(self):
print "I am wrapping Working."
Working().do()
return MutantReturnStatement()
This will obviously give the correct return and desired printout.
What you do is not a casting, it is a type conversion. Still, you could write something like
def cast_to(mytype: Type[any], obj: any):
if isinstance(obj, mytype):
return obj
else:
return mytype(obj)
class MutantReturnStatement(ReturnStatement):
def __init__(self, *args, **kwargs):
if isinstance(args[0], Working):
pass
# your custom logic here
# for the type conversion.
Usage:
cast_to(MutantReturnStatement, Working()).act()
# or simply
MutantReturnStatement(Working()).act()
(Note that in your example MutantReturnStatement does not have .do() member function.)

Categories