Short version: For normal Object members, this is simple - you just use self.member in the parent, and the child can override the member and everything is happily object orientated. But what about class members that may get overriden by a child class?
To make that clear:
I know in Python I can just give Classname.membername but how do I allow Class members to be overriden? For example I have
class BaseDB:
user_table = "users"
# Class member function
def make_sql():
return f'SELECT * from {BaseDB.user_table};'
# Boilerplate functions that use "user_table"
def load_users(self):
return db.connection.cursor.execute(BaseDB.make_sql())
class SomeDatabase(BaseDB):
user_table = "the_users_table"
# Somewhere else in the code....
dbwrapper = SomeDatabase()
dbwrapper.load_users() # This does not use the overwridden value in SomeDatabase, it uses the value form the parent class
What I'm looking for something like self, but for the Class, not for the object.
At first I thought I could try and use type(self).class_member .... Not sure if that would even work, but self might not be available, eg in a non-class member method.
My workaround at present is to use normal object members - right now I don't have a requirement to access these from a class method. The only reason why I want to make these into Class members is because the values are constant for the class, not the object.
Edit: Added the somewhat contrived Class member function make_sql and used it in the normal member function.
Note: The derived class only sets the class member - Nothing else is overridden.
Note #2 - This is not a major obstacle. If there is a solution, I am sure I can use it ... if not, I've been getting along without it fine, so I'm just asking to find out if I'm missing out on something.
EDIT #2:
I just thought I should put the code into my IDE and see if I had any errors (I'm lazy). The IDE told me I need to have a "self" on the class member so I annotated it with #classmember. The IDE told me "Well then you should have a cls parameter. VOILA! This solves the problem, of course.
I need to access a variable from a nested class. The objective is to create a Schema using the Marshmallow library. The code looks like this :
class ParserScheme(Schema):
class Meta:
# Here I meed to access the value of my_variable :
result = func(my_variable)
my_variable = 'foo'
my_parser = ParserScheme()
If I manage to pass my variable as a class attribute of the outer class (ParserScheme), then it is easy to get it into the inner class (Meta).
class ParserScheme(Schema):
class_attribute = my_variable
class Meta:
result = func(ParserScheme.class_attribute)
my_variable = 'foo'
my_parser = ParserScheme()
However I can't seem to find a way to dynamically set a class attribute. And if I set a "classic" attribute (I mean an attribute of instances of the class, not of the class itself), then I can't access it from the inner class.
I also thought of using a global variable, but that does not really quite satisfy me. Is there another way of doing this ?
I am rather new to OOP, and I am not sure I understand really well the concept of class attribute. I fear that there is an easy way to do that but I did not see it as I am to focused on the way I think this should work...
Your first example breaks because name my_variable is not yet defined when the class Meta statement's body is executed.
You second example won't work either for the same reason (my_variable is not yet defined when the class ParserScheme statement's body is executed), and if it was it would still break when executing the class Meta statement's body because it will be executed as part of the class ParserScheme statement's body hence before the name ParserScheme is defined.
What you have to understand here is that class and def are executable statements which (if at the top level of a module) are executed sequentially when the module is first imported into the current process. In the case of a class statement, the statement's body is first sequentially executed in a dedicated namespace then this namespace is passed to the metaclass constructor and used to create the class object's attributes (YourClass.__dict__).
To make a long story short: in a class statement body, you just cannot reference names that are not yet defined in the current or enclosing scope. Period.
The obvious solution here would be to define my_variable before the class statement, but I assume you want it to be more dynamic ? If yes, you'll have to define your class in a function:
def create_parser_class(my_variable):
class ParserScheme(Schema):
class Meta:
result = func(my_variable)
return ParserScheme
my_variable = 42
cls = create_parser_class(my_variable)
my_parser = cls()
But I can't garantee it will work out of the box (nor even work at all FWIW) with Marshmallow (which I never used but probably has some metaclass stuff happening). Also depending on what my_variable is used for, you may want to make sure you don't have two calls to create_parser_class with the same value as argument.
As a last note : you perhaps have a XY problem here - that's sometimes the case when someone asks how to do something a bit non-obvious or unusual. Perhaps you should edit your post to explain the "problem behind" - that is, the problem you are actually trying to solve with this "solution".
Oh and yes:
I am rather new to OOP, and I am not sure I understand really well the concept of class attribute
In Python, classes are objects too (instances of their metaclass, by default the type object), and as such they have their own attributes. Every name you define (with an assignment, a def statement, a class statement or an import statement) at the top-level of the class statement becomes an attribute of the class object (unless a custom metaclass makes some transformations on the way, that is).
Class attributes are accessible from the instances too (unless shadowed by an eponym instance variable), and are shared between all instances.
I am having a huge and confusing issue. I have a model, that most definitely has certain properties, let's call them, name and text, but for some reason when I try to instantiate an instance of that model, I get this error:
AttributeError: type object 'FakeModel' has no attribute 'text'
The model class looks something like this:
class FakeModel(ndb.Model):
name = ndb.StringProperty()
text = ndb.TextProperty(required=True)
created = ndb.DateTimeProperty(auto_now_add=True)
and I'm calling it in a route/endpoint like this:
model = FakeModel(
id=id_that_is_calculated_in_code,
name=name, #variable 'name' got from request
text=text #variable 'text' got from request
)
Strange things:
- This worked plenty of times before, I have no idea what is causing this to break now.
- When I remove the 'text' specification from the constructor, I get another error telling me that i need to put that there because it's required. This means it definitely is looking at the right model class.
BadValueError: Entity has uninitialized properties: text
- Sometimes if I switch the line order of the properties, I instead get an error telling me that 'name' is not a property.
EDIT: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I found that this error disappears when I remove the import of a different model class from a different file. This undefined behavior is replaced with other seemingly random failures elsewhere in the code.
I have a polymodel class from which other classes inherit; some models store a KeyProperty to that parent class, and store keys of it's children i.e.
class Parent(polymodel.PolyModel):
def method1(self):
pass
class Child(Parent):
def method1(self):
"""
some logic happens here which does not happen
in the parent's method, which is meant to be overloaded
"""
class OtherEntity(ndb.Model):
enkey = ndb.KeyProperty(kind=Parent)
At seemingly random times (not every time), when I have an OtherEntity instance and call
instance.enkey.get().method1()
I get a failure or None return because the code is treating the entity pulled by the key as a Parent object, not a Child, and so calling Parent's version of method1() which is just pass. This has been verified with logging.
It's very strange to me because the class I imported was not related to this "FakeModel" class at all, and neither was the file it was imported from. Overall, It appears that i'm seeing some type of undefined behavior; something I have never seen before with python, or with google app engine. I suppose I'm now wondering if 'undefined behavior' as in that which can occur in C/C++ can happen in python/GAE, and if so what it's sources are.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I feel totally crazy, and I have no idea what is going on. Please help.
Let's say you have an object that was instantiated from a class inside a module.
Now, you reload that module.
The next thing you'd like to do is make that reload affect that class.
mymodule.py
---
class ClassChange():
def run(self):
print 'one'
myexperiment.py
---
import mymodule
from mymodule import ClassChange # why is this necessary?
myObject = ClassChange()
myObject.run()
>>> one
### later, i changed this file, so that it says print 'two'
reload(mymodule)
# trick to change myObject needed here
myObject.run()
>>> two
Do you have to make a new ClassChange object, copy myObject into that, and delete the old myObject? Or is there a simpler way?
Edit: The run() method seems like a static class style method but that was only for the sake of brevity. I'd like the run() method to operate on data inside the object, so a static module function wouldn't do...
To update all instances of a class, it is necessary to keep track somewhere about those instances -- typically via weak references (weak value dict is handiest and general) so the "keeping track" functionality won't stop unneeded instances from going away, of course!
You'd normally want to keep such a container in the class object, but, in this case, since you'll be reloading the module, getting the old class object is not trivial; it's simpler to work at module level.
So, let's say that an "upgradable module" needs to define, at its start, a weak value dict (and an auxiliary "next key to use" int) with, say, conventional names:
import weakref
class _List(list): pass # a weakly-referenceable sequence
_objs = weakref.WeakValueDictionary()
_nextkey = 0
def _register(obj):
_objs[_nextkey] = List((obj, type(obj).__name__))
_nextkey += 1
Each class in the module must have, typically in __init__, a call _register(self) to register new instances.
Now the "reload function" can get the roster of all instances of all classes in this module by getting a copy of _objs before it reloads the module.
If all that's needed is to change the code, then life is reasonably easy:
def reload_all(amodule):
objs = getattr(amodule, '_objs', None)
reload(amodule)
if not objs: return # not an upgraable-module, or no objects
newobjs = getattr(amodule, '_objs', None)
for obj, classname in objs.values():
newclass = getattr(amodule, classname)
obj.__class__ = newclass
if newobjs: newobjs._register(obj)
Alas, one typically does want to give the new class a chance to upgrade an object of the old class to itself more finely, e.g. by a suitable class method. That's not too hard either:
def reload_all(amodule):
objs = getattr(amodule, '_objs', None)
reload(amodule)
if not objs: return # not an upgraable-module, or no objects
newobjs = getattr(amodule, '_objs', None)
for obj, classname in objs:
newclass = getattr(amodule, classname)
upgrade = getattr(newclass, '_upgrade', None)
if upgrade:
upgrade(obj)
else:
obj.__class__ = newclass
if newobjs: newobjs._register(obj)
For example, say the new version of class Zap has renamed an attribute from foo to bar. This could be the code of the new Zap:
class Zap(object):
def __init__(self):
_register(self)
self.bar = 23
#classmethod
def _upgrade(cls, obj):
obj.bar = obj.foo
del obj.foo
obj.__class__ = cls
This is NOT all -- there's a LOT more to say on the subject -- but, it IS the gist, and the answer is WAY long enough already (and I, exhausted enough;-).
You have to make a new object. There's no way to magically update the existing objects.
Read the reload builtin documentation - it is very clear. Here's the last paragraph:
If a module instantiates instances of a class, reloading the module that defines the class does not affect the method definitions of the instances — they continue to use the old class definition. The same is true for derived classes.
There are other caveats in the documentation, so you really should read it, and consider alternatives. Maybe you want to start a new question with why you want to use reload and ask for other ways of achieving the same thing.
My approach to this is the following:
Look through all imported modules and reload only those with a new .py file (as compared to the existing .pyc file)
For every function and class method that is reloaded, set old_function.__code__ = new_function.__code__.
For every reloaded class, use gc.get_referrers to list instances of the class and set their __class__ attribute to the new version.
Advantages to this approach are:
Usually no need to reload modules in any particular order
Usually only need to reload the modules with changed code and no more
Don't need to modify classes to keep track of their instances
You can read about the technique (and its limitations) here:
http://luke-campagnola.blogspot.com/2010/12/easy-automated-reloading-in-python.html
And you can download the code here:
http://luke.campagnola.me/code/downloads/reload.py
You have to get the new class from the fresh module and assign it back to the instance.
If you could trigger this operation anytime you use an instance with this mixin:
import sys
class ObjDebug(object):
def __getattribute__(self,k):
ga=object.__getattribute__
sa=object.__setattr__
cls=ga(self,'__class__')
modname=cls.__module__
mod=__import__(modname)
del sys.modules[modname]
reload(mod)
sa(self,'__class__',getattr(mod,cls.__name__))
return ga(self,k)
The following code does what you want, but please don't use it (at least not until you're very sure you're doing the right thing), I'm posting it for explanation purposes only.
mymodule.py:
class ClassChange():
#classmethod
def run(cls,instance):
print 'one',id(instance)
myexperiment.py:
import mymodule
myObject = mymodule.ClassChange()
mymodule.ClassChange.run(myObject)
# change mymodule.py here
reload(mymodule)
mymodule.ClassChange.run(myObject)
When in your code you instanciate myObject, you get an instance of ClassChange. This instance has an instance method called run. The object keeps this instance method (for the reason explained by nosklo) even when reloading, because reloading only reloads the class ClassChange.
In my code above, run is a class method. Class methods are always bound to and operate on the class, not the instance (which is why their first argument is usually called cls, not self). Wenn ClassChange is reloaded, so is this class method.
You can see that I also pass the instance as an argument to work with the correct (same) instance of ClassChange. You can see that because the same object id is printed in both cases.
I'm not sure if this is the best way to do it, or meshes with what you want to do... but this may work for you. If you want to change the behavior of a method, for all objects of a certain type... just use a function variable. For example:
def default_behavior(the_object):
print "one"
def some_other_behavior(the_object):
print "two"
class Foo(object):
# Class variable: a function that has the behavior
# (Takes an instance of a Foo as argument)
behavior = default_behavior
def __init__(self):
print "Foo initialized"
def method_that_changes_behavior(self):
Foo.behavior(self)
if __name__ == "__main__":
foo = Foo()
foo.method_that_changes_behavior() # prints "one"
Foo.behavior = some_other_behavior
foo.method_that_changes_behavior() # prints "two"
# OUTPUT
# Foo initialized
# one
# two
You can now have a class that is responsible for reloading modules, and after reloading, setting Foo.behavior to something new. I tried out this code. It works fine :-).
Does this work for you?
There are tricks to make what you want possible.
Someone already mentioned that you can have a class that keeps a list of its instances, and then changing the class of each instance to the new one upon reload.
However, that is not efficient. A better method is to change the old class so that it is the same as the new class.
I'm teaching myself Python and my most recent lesson was that Python is not Java, and so I've just spent a while turning all my Class methods into functions.
I now realise that I don't need to use Class methods for what I would done with static methods in Java, but now I'm not sure when I would use them. All the advice I can find about Python Class methods is along the lines of newbies like me should steer clear of them, and the standard documentation is at its most opaque when discussing them.
Does anyone have a good example of using a Class method in Python or at least can someone tell me when Class methods can be sensibly used?
Class methods are for when you need to have methods that aren't specific to any particular instance, but still involve the class in some way. The most interesting thing about them is that they can be overridden by subclasses, something that's simply not possible in Java's static methods or Python's module-level functions.
If you have a class MyClass, and a module-level function that operates on MyClass (factory, dependency injection stub, etc), make it a classmethod. Then it'll be available to subclasses.
Factory methods (alternative constructors) are indeed a classic example of class methods.
Basically, class methods are suitable anytime you would like to have a method which naturally fits into the namespace of the class, but is not associated with a particular instance of the class.
As an example, in the excellent unipath module:
Current directory
Path.cwd()
Return the actual current directory; e.g., Path("/tmp/my_temp_dir"). This is a class method.
.chdir()
Make self the current directory.
As the current directory is process wide, the cwd method has no particular instance with which it should be associated. However, changing the cwd to the directory of a given Path instance should indeed be an instance method.
Hmmm... as Path.cwd() does indeed return a Path instance, I guess it could be considered to be a factory method...
Think about it this way: normal methods are useful to hide the details of dispatch: you can type myobj.foo() without worrying about whether the foo() method is implemented by the myobj object's class or one of its parent classes. Class methods are exactly analogous to this, but with the class object instead: they let you call MyClass.foo() without having to worry about whether foo() is implemented specially by MyClass because it needed its own specialized version, or whether it is letting its parent class handle the call.
Class methods are essential when you are doing set-up or computation that precedes the creation of an actual instance, because until the instance exists you obviously cannot use the instance as the dispatch point for your method calls. A good example can be viewed in the SQLAlchemy source code; take a look at the dbapi() class method at the following link:
https://github.com/zzzeek/sqlalchemy/blob/ab6946769742602e40fb9ed9dde5f642885d1906/lib/sqlalchemy/dialects/mssql/pymssql.py#L47
You can see that the dbapi() method, which a database backend uses to import the vendor-specific database library it needs on-demand, is a class method because it needs to run before instances of a particular database connection start getting created — but that it cannot be a simple function or static function, because they want it to be able to call other, supporting methods that might similarly need to be written more specifically in subclasses than in their parent class. And if you dispatch to a function or static class, then you "forget" and lose the knowledge about which class is doing the initializing.
I recently wanted a very light-weight logging class that would output varying amounts of output depending on the logging level that could be programmatically set. But I didn't want to instantiate the class every time I wanted to output a debugging message or error or warning. But I also wanted to encapsulate the functioning of this logging facility and make it reusable without the declaration of any globals.
So I used class variables and the #classmethod decorator to achieve this.
With my simple Logging class, I could do the following:
Logger._level = Logger.DEBUG
Then, in my code, if I wanted to spit out a bunch of debugging information, I simply had to code
Logger.debug( "this is some annoying message I only want to see while debugging" )
Errors could be out put with
Logger.error( "Wow, something really awful happened." )
In the "production" environment, I can specify
Logger._level = Logger.ERROR
and now, only the error message will be output. The debug message will not be printed.
Here's my class:
class Logger :
''' Handles logging of debugging and error messages. '''
DEBUG = 5
INFO = 4
WARN = 3
ERROR = 2
FATAL = 1
_level = DEBUG
def __init__( self ) :
Logger._level = Logger.DEBUG
#classmethod
def isLevel( cls, level ) :
return cls._level >= level
#classmethod
def debug( cls, message ) :
if cls.isLevel( Logger.DEBUG ) :
print "DEBUG: " + message
#classmethod
def info( cls, message ) :
if cls.isLevel( Logger.INFO ) :
print "INFO : " + message
#classmethod
def warn( cls, message ) :
if cls.isLevel( Logger.WARN ) :
print "WARN : " + message
#classmethod
def error( cls, message ) :
if cls.isLevel( Logger.ERROR ) :
print "ERROR: " + message
#classmethod
def fatal( cls, message ) :
if cls.isLevel( Logger.FATAL ) :
print "FATAL: " + message
And some code that tests it just a bit:
def logAll() :
Logger.debug( "This is a Debug message." )
Logger.info ( "This is a Info message." )
Logger.warn ( "This is a Warn message." )
Logger.error( "This is a Error message." )
Logger.fatal( "This is a Fatal message." )
if __name__ == '__main__' :
print "Should see all DEBUG and higher"
Logger._level = Logger.DEBUG
logAll()
print "Should see all ERROR and higher"
Logger._level = Logger.ERROR
logAll()
Alternative constructors are the classic example.
It allows you to write generic class methods that you can use with any compatible class.
For example:
#classmethod
def get_name(cls):
print cls.name
class C:
name = "tester"
C.get_name = get_name
#call it:
C.get_name()
If you don't use #classmethod you can do it with self keyword but it needs an instance of Class:
def get_name(self):
print self.name
class C:
name = "tester"
C.get_name = get_name
#call it:
C().get_name() #<-note the its an instance of class C
When a user logs in on my website, a User() object is instantiated from the username and password.
If I need a user object without the user being there to log in (e.g. an admin user might want to delete another users account, so i need to instantiate that user and call its delete method):
I have class methods to grab the user object.
class User():
#lots of code
#...
# more code
#classmethod
def get_by_username(cls, username):
return cls.query(cls.username == username).get()
#classmethod
def get_by_auth_id(cls, auth_id):
return cls.query(cls.auth_id == auth_id).get()
I think the most clear answer is AmanKow's one. It boils down to how u want to organize your code. You can write everything as module level functions which are wrapped in the namespace of the module i.e
module.py (file 1)
---------
def f1() : pass
def f2() : pass
def f3() : pass
usage.py (file 2)
--------
from module import *
f1()
f2()
f3()
def f4():pass
def f5():pass
usage1.py (file 3)
-------------------
from usage import f4,f5
f4()
f5()
The above procedural code is not well organized, as you can see after only 3 modules it gets confusing, what is each method do ? You can use long descriptive names for functions(like in java) but still your code gets unmanageable very quick.
The object oriented way is to break down your code into manageable blocks i.e Classes & objects and functions can be associated with objects instances or with classes.
With class functions you gain another level of division in your code compared with module level functions.
So you can group related functions within a class to make them more specific to a task that you assigned to that class. For example you can create a file utility class :
class FileUtil ():
def copy(source,dest):pass
def move(source,dest):pass
def copyDir(source,dest):pass
def moveDir(source,dest):pass
//usage
FileUtil.copy("1.txt","2.txt")
FileUtil.moveDir("dir1","dir2")
This way is more flexible and more maintainable, you group functions together and its more obvious to what each function do. Also you prevent name conflicts, for example the function copy may exist in another imported module(for example network copy) that you use in your code, so when you use the full name FileUtil.copy() you remove the problem and both copy functions can be used side by side.
Honestly? I've never found a use for staticmethod or classmethod. I've yet to see an operation that can't be done using a global function or an instance method.
It would be different if python used private and protected members more like Java does. In Java, I need a static method to be able to access an instance's private members to do stuff. In Python, that's rarely necessary.
Usually, I see people using staticmethods and classmethods when all they really need to do is use python's module-level namespaces better.
I used to work with PHP and recently I was asking myself, whats going on with this classmethod? Python manual is very technical and very short in words so it wont help with understanding that feature. I was googling and googling and I found answer -> http://code.anjanesh.net/2007/12/python-classmethods.html.
If you are lazy to click it. My explanation is shorter and below. :)
in PHP (maybe not all of you know PHP, but this language is so straight forward that everybody should understand what I'm talking about) we have static variables like this:
class A
{
static protected $inner_var = null;
static public function echoInnerVar()
{
echo self::$inner_var."\n";
}
static public function setInnerVar($v)
{
self::$inner_var = $v;
}
}
class B extends A
{
}
A::setInnerVar(10);
B::setInnerVar(20);
A::echoInnerVar();
B::echoInnerVar();
The output will be in both cases 20.
However in python we can add #classmethod decorator and thus it is possible to have output 10 and 20 respectively. Example:
class A(object):
inner_var = 0
#classmethod
def setInnerVar(cls, value):
cls.inner_var = value
#classmethod
def echoInnerVar(cls):
print cls.inner_var
class B(A):
pass
A.setInnerVar(10)
B.setInnerVar(20)
A.echoInnerVar()
B.echoInnerVar()
Smart, ain't?
Class methods provide a "semantic sugar" (don't know if this term is widely used) - or "semantic convenience".
Example: you got a set of classes representing objects. You might want to have the class method all() or find() to write User.all() or User.find(firstname='Guido'). That could be done using module level functions of course...
if you are not a "programmer by training", this should help:
I think I have understood the technical explanations above and elsewhere on the net, but I was always left with a question "Nice, but why do I need it? What is a practical, use case?". and now life gave me a good example that clarified all:
I am using it to control the global-shared variable that is shared among instances of a class instantiated by multi-threading module. in humane language, I am running multiple agents that create examples for deep learning IN PARALLEL. (imagine multiple players playing ATARI game at the same time and each saving the results of their game to one common repository (the SHARED VARIABLE))
I instantiate the players/agents with the following code (in Main/Execution Code):
a3c_workers = [A3C_Worker(self.master_model, self.optimizer, i, self.env_name, self.model_dir) for i in range(multiprocessing.cpu_count())]
it creates as many players as there are processor cores on my comp
A3C_Worker - is a class that defines the agent
a3c_workers - is a list of the instances of that class (i.e. each instance is one player/agent)
now i want to know how many games have been played across all players/agents thus within the A3C_Worker definition I define the variable to be shared across all instances:
class A3C_Worker(threading.Thread):
global_shared_total_episodes_across_all_workers = 0
now as the workers finish their games they increase that count by 1 each for each game finished
at the end of my example generation i was closing the instances but the shared variable had assigned the total number of games played. so when I was re-running it again my initial total number of episodes was that of the previous total. but i needed that count to represent that value for each run individually
to fix that i specified :
class A3C_Worker(threading.Thread):
#classmethod
def reset(cls):
A3C_Worker.global_shared_total_episodes_across_all_workers = 0
than in the execution code i just call:
A3C_Worker.reset()
note that it is a call to the CLASS overall not any INSTANCE of it individually. thus it will set my counter to 0 for every new agent I initiate from now on.
using the usual method definition def play(self):, would require us to reset that counter for each instance individually, which would be more computationally demanding and difficult to track.
What just hit me, coming from Ruby, is that a so-called class method and a so-called instance method is just a function with semantic meaning applied to its first parameter, which is silently passed when the function is called as a method of an object (i.e. obj.meth()).
Normally that object must be an instance but the #classmethod method decorator changes the rules to pass a class. You can call a class method on an instance (it's just a function) - the first argument will be its class.
Because it's just a function, it can only be declared once in any given scope (i.e. class definition). If follows therefore, as a surprise to a Rubyist, that you can't have a class method and an instance method with the same name.
Consider this:
class Foo():
def foo(x):
print(x)
You can call foo on an instance
Foo().foo()
<__main__.Foo instance at 0x7f4dd3e3bc20>
But not on a class:
Foo.foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unbound method foo() must be called with Foo instance as first argument (got nothing instead)
Now add #classmethod:
class Foo():
#classmethod
def foo(x):
print(x)
Calling on an instance now passes its class:
Foo().foo()
__main__.Foo
as does calling on a class:
Foo.foo()
__main__.Foo
It's only convention that dictates that we use self for that first argument on an instance method and cls on a class method. I used neither here to illustrate that it's just an argument. In Ruby, self is a keyword.
Contrast with Ruby:
class Foo
def foo()
puts "instance method #{self}"
end
def self.foo()
puts "class method #{self}"
end
end
Foo.foo()
class method Foo
Foo.new.foo()
instance method #<Foo:0x000000020fe018>
The Python class method is just a decorated function and you can use the same techniques to create your own decorators. A decorated method wraps the real method (in the case of #classmethod it passes the additional class argument). The underlying method is still there, hidden but still accessible.
footnote: I wrote this after a name clash between a class and instance method piqued my curiosity. I am far from a Python expert and would like comments if any of this is wrong.
This is an interesting topic. My take on it is that python classmethod operates like a singleton rather than a factory (which returns a produced an instance of a class). The reason it is a singleton is that there is a common object that is produced (the dictionary) but only once for the class but shared by all instances.
To illustrate this here is an example. Note that all instances have a reference to the single dictionary. This is not Factory pattern as I understand it. This is probably very unique to python.
class M():
#classmethod
def m(cls, arg):
print "arg was", getattr(cls, "arg" , None),
cls.arg = arg
print "arg is" , cls.arg
M.m(1) # prints arg was None arg is 1
M.m(2) # prints arg was 1 arg is 2
m1 = M()
m2 = M()
m1.m(3) # prints arg was 2 arg is 3
m2.m(4) # prints arg was 3 arg is 4 << this breaks the factory pattern theory.
M.m(5) # prints arg was 4 arg is 5
I was asking myself the same question few times. And even though the guys here tried hard to explain it, IMHO the best answer (and simplest) answer I have found is the description of the Class method in the Python Documentation.
There is also reference to the Static method. And in case someone already know instance methods (which I assume), this answer might be the final piece to put it all together...
Further and deeper elaboration on this topic can be found also in the documentation:
The standard type hierarchy (scroll down to Instance methods section)
#classmethod can be useful for easily instantiating objects of that class from outside resources. Consider the following:
import settings
class SomeClass:
#classmethod
def from_settings(cls):
return cls(settings=settings)
def __init__(self, settings=None):
if settings is not None:
self.x = settings['x']
self.y = settings['y']
Then in another file:
from some_package import SomeClass
inst = SomeClass.from_settings()
Accessing inst.x will give the same value as settings['x'].
A class defines a set of instances, of course. And the methods of a class work on the individual instances. The class methods (and variables) a place to hang other information that is related to the set of instances over all.
For example if your class defines a the set of students you might want class variables or methods which define things like the set of grade the students can be members of.
You can also use class methods to define tools for working on the entire set. For example Student.all_of_em() might return all the known students. Obviously if your set of instances have more structure than just a set you can provide class methods to know about that structure. Students.all_of_em(grade='juniors')
Techniques like this tend to lead to storing members of the set of instances into data structures that are rooted in class variables. You need to take care to avoid frustrating the garbage collection then.
Classes and Objects concepts are very useful in organizing things. It's true that all the operations that can be done by a method can also be done using a static function.
Just think of a scenario, to build a Students Databases System to maintain student details.
You need to have details about students, teachers and staff. You need to build functions to calculate fees, salary, marks, etc. Fees and marks are only applicable for students, salary is only applicable for staff and teachers. So if you create separate classes for every type of people, the code will be organized.