I am on a Python 3.6 project that uses Sqlalchemy where we want another layer of abstraction over Sqlalchemy. This will allow us to more easily replace Sqlalchemy with another library if desired.
In this example it is the DbHelper class:
dbhelper.py
from dbconn import dbconn
from models.animals import Dogs
class DbHelper():
#staticmethod
def get_dog_by_nickname(nickname):
return dbconn.session.query(Dogs).get(nickname)
main.py
from dbhelper import DbHelper
class Dog():
def __init__(self, nickname, breed, age):
self.nickname = nickname
self.breed = breed
self.age = age
#classmethod
def using_nickname(cls, nickname):
row = DbHelper.get_dog_by_nickname(nickname)
return Dog(row.id, row.breed, row.age)
dog = Dog.using_nickname('Tom')
Question: Is there a better method than creating the DbHelper class for use as a container and having only staticmethod in it? I have read that this is not pythonic.
Converting all the staticmethod functions in dbhelper.py to regular methods will populate the namespace when we do from dbhelper import *
Yes, there is a better solution than creating a class full of staticmethods: Just don't create the class, and make them all module-level functions:
from models.animals import Dogs
dbconn = ...
def get_dog_by_nickname(nickname):
return dbconn.session.query(Dogs).get(nickname)
The only real point of a class full of staticmethods is to provide a namespace for all those functions to live in. A module already is a namespace for all those functions to live in. And, because it's more directly supported by the language syntax, it means you can more easily go around the namespacing when you want to do so explicitly (e.g., from dbhelper import ...).
You say:
Converting all the staticmethod functions in dbhelper.py to regular methods will populate the namespace when we do from dbhelper import *
But the answer to that is obvious: Don't from dbhelper import *, just import dbhelper. Then, all the code that you would have written with DbHelper.spam() becomes dbhelper.spam().
If you really want two levels of namespace, you can just use a package with a submodule, rather than a module with a class. But I can't see any good reason you'd need two levels of namespace here.
Another alternative (as suggested by juanpa.arrivillaga in the comments) is to turn this into a real class, where each instance (even if there will probably only be one in your real code) has its own self.dbconn instead of using a module global. That dbconn can either be passed into the __init__, or constructed directly inside the __init__. For example:
class DbHelper:
def __init__(self, dbname, otherdbparam):
self.dbconn = dblib.connect(dbname, otherdbparam)
def get_dog_by_nickname(self, nickname):
return self.dbconn.session.query(Dogs).get(nickname)
Notice that we're using normal methods, and accessing a normal instance variable. This is what a class is for—to wrap up some state together with the methods that transform that state.
How do you decide between the two? Well, if there's only ever going to be one dbconn per process, they're functionally equivalent, but conceptually they have different connotations. If you think of a DbHelper as a database, both the connection and the database behavior, it should be a class, and you should instantiate an instance of that class and use it that way. If you think of it as just a bunch of helper functions that operate on a dbconn that has its own independent existence, it should be a flat module.
In some languages (like Java), there is another point to using a class full of staticmethod-equivalents: the language either doesn't support "free functions", or makes them a completely different kind of thing from methods. But that isn't true in Python.
While we're at it, do you want your module to export Dogs and dbconn as a "public" part of the interface? If not, you should add an __all__ spec to the top of your module, like this:
from models.animals import Dogs
__all__ = [
'get_dog_by_nickname',
...
]
dbconn = ...
def get_dog_by_nickname(nickname):
return dbconn.session.query(Dogs).get(nickname)
Or, alternatively, name all your "private" module members with underscores:
from models.animals import Dogs as _Dogs
_dbconn = ...
def get_dog_by_nickname(nickname):
return _dbconn.session.query(_Dogs).get(nickname)
Either way, users of your module can still access the "private" data, but it won't show up in from dbhelper import *, help(dbhelper), the default autocomplete in many IDEs, etc.
I'm new at Python and previously I've been using languages like Swift, where import is not a big deal: you're just defining a new class and can access it from another part of your program.
I can't use this way with Python because here import works in the other way: you can't make cyclic imports, where two files import each other. I understand that I'm facing this problem because of using the language in a wrong way but I don't understand how to avoid it.
I mean, in most cases you just can solve this problem by combining two classes into a single file but it doesn't feel right. Also, I've found advice like "move your import statement to the end of file" but it doesn't feel like a good idea too.
I would like to understand the Python's philosophy, if you will. How should I organize my project and what should I be guided by, when deciding on making a class in a separate file?
You certainly can import child from parent and parent from child. The key to making this work is for child not to probe too deeply into parent from its module-level code, because the parent module is only partly loaded at the time that the Python runs the module-level code in child.
Here's what happens when you import child from parent and parent from child (assuming parent is loaded first):
Code at the module level of parent runs until it reaches a statement that loads child (either import child or from child import something). By "module level", I mean the statements that aren't within a class or function definition. The classes and functions defined at the module level will also be created as objects within the module. However, the functions and class methods themselves will not be run yet.
When Python gets to the import child statement (or equivalent) in parent's module-level code, it will stop running the parent code and begin running the module-level code in child. If child imports parent via import parent or from parent import something, it will get the parent module in its current, partially constructed state. So module-level code in child cannot access objects that are defined below import child in parent.py.
Once child's module-level code finishes running, control will return to parent below the import child statement, and Python will finish running all of the module-level code in parent.
This process will give you trouble if child's module-level code tries to access objects that are defined in parent after the import child statement (since parent is only partially finished when child loads). The solution to this is to import parent at the module level of child but defer accessing objects within parent from child until after child and parent have finished loading. In particular, instead of using from parent import something in child's module-level code, you may need to use import parent, then access parent.something from inside function or method code in child. This is safe to do because those functions and methods won't be run until after child and parent finish running, at which point all the elements of the parent module are correctly defined.
Here's an example of what I mean, using the setup you described in a comment. If you give more information on the code that is giving you problems, I could tailor this more closely.
Version 1 (won't work)
__main__.py:
from user import User
u = User()
user.py:
from data_manager import DataManager
...
class User:
def __init__(self, data_manager=None):
if data_manager is None:
data_manager = DataManager(user=self)
self.data_manager = data_manager
data_manager.py:
# next line will fail because user.py has been partly loaded
# and user.User doesn't exist yet
from user import User
...
class DataManager:
def __init__(self, user=None):
...
if user is None:
user = User(data_manager=self)
self.user = user
Version 2 (will work)
__main__.py:
from user import User
u = User()
user.py:
import data_manager as dm
...
class User:
def __init__(self, data_manager=None):
if data_manager is None:
data_manager = dm.DataManager(user=self)
self.data_manager = data_manager
data_manager.py:
import user as user_module
...
# this defines a class which will eventually create an instance
# of user.User, but it won't try to do that until control returns
# to __main__.py, by which point the `user` and `data_manager`
# modules are fully defined
class DataManager:
def __init__(self, user=None):
...
if user is None:
user = user_module.User(data_manager=self)
self.user = user
Note that references in your classes' __init__ methods don't get resolved until the class is actually instantiated. i.e., the user = user_module.User(data_manager=self) line does something like this: "look in the current module for an object called user_module; look in that object for a User attribute; construct an object of that class". The important thing is that data_manager can safely import the user module early on (the module exists already, even though it is only partly constructed), but the code above won't actually look for anything inside the user module until a DataManager object is instantiated, by which time user.User will be properly defined.
I can't use this way with Python because here import works in the other way: you can't make cyclic imports, where two files import each other.
Yes you can!
Say we have two files in the same working directory:
#file1.py
import file2
x = 22
y = 'spam'
print(x)
print(y)
and
#file2.py
import file1
print("file1")
Notice what happens when we import file1.py
>>> import file1
file1
22
spam
file1.py imports file2.py and file2.py imports file1.py.
This problem happens because you're writing Python program like you would write Swift or Java program. Such approach never works well: every language is different and has different best practices. If you write unpythonic code, not only it looks ugly and undecipherable to other Python developers, you're struggling with the language instead of enjoying it.
Just structure your code like python developers structure it. Group related classes in one module. If there's a rare case where there's hard to avoid import cycles (almost never happens), import offending dependency in the function or method instead of global scope.
I've written a module called Consumer.py, containing a class (Consumer). This class is initialized using a configuration file thay contains different parameters it uses for computation and the name of a loq que used for logging.
I want to write unit tests for this class so i've made a script called test_Consumer.py with a class called TestConsumerMethods(unittest.TestCase).
Now, what i've done is create a new object of the Consumer class called cons, and then i use that to call on the class methods for testing. For example, Consumer has a simple method that checks if a file exists in a given directory. The test i've made looks like this
import Consumer
from Consumer import Consumer
cons = Consumer('mockconfig.config', 'logque1')
class TestConsumerMethods(unittest.TestCase):
def test_fileExists(self):
self.assertEqual(cons.file_exists('./dir/', 'thisDoesntExist.config), False)
self. assertEqual(cons.file_exists('./dir/', thisDoesExist.config), True)
Is this the correct way to test my class? I mean, ideally i'd like to just use the class methods without having to instantiate the class because to "isolate" the code, right?
Don't make a global object to test against, as it opens up the possibility that some state will get set on it by one test, and affect another.
Each test should run in isolation and be completely independent from others.
Instead, either create the object in your test, or have it automatically created for each test by putting it in the setUp method:
import Consumer
from Consumer import Consumer
class TestConsumerMethods(unittest.TestCase):
def setUp(self):
self.cons = Consumer('mockconfig.config', 'logque1')
def test_fileExists(self):
self.assertEqual(self.cons.file_exists('./dir/', 'thisDoesntExist.config), False)
self. assertEqual(self.cons.file_exists('./dir/', thisDoesExist.config), True)
As far as whether you actually have to instantiate your class at all, that depends on the implementation of the class. I think generally you'd expect to instantiate a class to test its methods.
I'm not sure if that's what you're searching for, but you could add your tests at the end of your file like this :
#!/usr/bin/python
...
class TestConsumerMethods(...):
...
if __name__ == "__main__":
# add your tests here.
This way, by executing the file containing the class definition, you execute the tests you put in the if statement.
This way the tests will only be executed if you directly execute the file itself, but not if you import the class from it.
I have a class-factory F that generates classes. It takes no arguments other than a name. I'd like to be able to wrap this method and use it like this:
from myproject.myfactory.virtualmodule import Foo
"myfactory" is a real module in the project, but I want virtualmodule to be something that pretends to be a module.
Whenever I import something from virtualmodule I want it to build a new class using my factory method and make it look as if that was imported.
Can this be done? Is there a pattern that will allow me to wrap a class-factory as a module?
Thanks!
--
UPDATE0: Why do I need this? It's actually to test a process that will be run on a grid which requires that all classes should be importable.
An instance of the auto-generated class will be serialized on my PC and then unserialized on each of the grid nodes. If the class cannot be imported on the grid node the unserialize will fail.
If I hijack the import mechanism as an interface for making my test-classes, then I know for sure that anything I can import on my PC can be re-created exactly the same on the grid. That will satisfy my test's requirements.
You can stuff an arbitrary object into the sys.modules structure:
import sys
class VirtualModule(object):
def __init__(self, name):
self.__name__ = name.rsplit('.', 1)[-1]
self.__package__ = name
self.__loader__ = None
def __getattr__(self, name):
if name is valid:
# Return dynamic classes here
return VirtualClass(name)
raise AttributeError(name)
virtual_module_name = 'myproject.myfactory.virtualmodule'
sys.modules[virtual_module_name] = VirtualModule(virtual_module_name)
The Python import machinery will look up objects using attribute access, triggering the __getattr__ method on your VirtualModule instance.
Do this in the myproject/__init__.py or myproject/myfactory/__init__.py file and you are all set to go. The myproject.myfactory package does need to exist for the import machinery to find the myproject.myfactory.virtualmodule object.
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.