I keep seeing the following decorators used: #staticmethod, #property for example:
#staticmethod
def add_url():
return reverse('add_user')
#property
def password_not_expired(self):
return not self.password_expired
Could someone explain when to use one over the other? Say I want to add this code:
def get_user_type(self):
return self.user_type
I would use a #staticmethod method right?
You can't use self in a #staticmethod. Because the only thing #staticmethod does is make the function not be passed self. Look in your own example: add_url doesn't take a self argument.
"static" here is in the entirely misleading sense of how C++ and Java use it. A Python #staticmethod is really just a regular function that happens to live in a class, nothing to do with whether values are changed.
You can use #property without writing a setter. In fact, that's probably the most common way to use it.
Related
I just can't see why do we need to use #staticmethod. Let's start with an exmaple.
class test1:
def __init__(self,value):
self.value=value
#staticmethod
def static_add_one(value):
return value+1
#property
def new_val(self):
self.value=self.static_add_one(self.value)
return self.value
a=test1(3)
print(a.new_val) ## >>> 4
class test2:
def __init__(self,value):
self.value=value
def static_add_one(self,value):
return value+1
#property
def new_val(self):
self.value=self.static_add_one(self.value)
return self.value
b=test2(3)
print(b.new_val) ## >>> 4
In the example above, the method, static_add_one , in the two classes do not require the instance of the class(self) in calculation.
The method static_add_one in the class test1 is decorated by #staticmethod and work properly.
But at the same time, the method static_add_one in the class test2 which has no #staticmethod decoration also works properly by using a trick that provides a self in the argument but doesn't use it at all.
So what is the benefit of using #staticmethod? Does it improve the performance? Or is it just due to the zen of python which states that "Explicit is better than implicit"?
The reason to use staticmethod is if you have something that could be written as a standalone function (not part of any class), but you want to keep it within the class because it's somehow semantically related to the class. (For instance, it could be a function that doesn't require any information from the class, but whose behavior is specific to the class, so that subclasses might want to override it.) In many cases, it could make just as much sense to write something as a standalone function instead of a staticmethod.
Your example isn't really the same. A key difference is that, even though you don't use self, you still need an instance to call static_add_one --- you can't call it directly on the class with test2.static_add_one(1). So there is a genuine difference in behavior there. The most serious "rival" to a staticmethod isn't a regular method that ignores self, but a standalone function.
Today I suddenly find a benefit of using #staticmethod.
If you created a staticmethod within a class, you don't need to create an instance of the class before using the staticmethod.
For example,
class File1:
def __init__(self, path):
out=self.parse(path)
def parse(self, path):
..parsing works..
return x
class File2:
def __init__(self, path):
out=self.parse(path)
#staticmethod
def parse(path):
..parsing works..
return x
if __name__=='__main__':
path='abc.txt'
File1.parse(path) #TypeError: unbound method parse() ....
File2.parse(path) #Goal!!!!!!!!!!!!!!!!!!!!
Since the method parse is strongly related to the classes File1 and File2, it is more natural to put it inside the class. However, sometimes this parse method may also be used in other classes under some circumstances. If you want to do so using File1, you must create an instance of File1 before calling the method parse. While using staticmethod in the class File2, you may directly call the method by using the syntax File2.parse.
This makes your works more convenient and natural.
I will add something other answers didn't mention. It's not only a matter of modularity, of putting something next to other logically related parts. It's also that the method could be non-static at other point of the hierarchy (i.e. in a subclass or superclass) and thus participate in polymorphism (type based dispatching). So if you put that function outside the class you will be precluding subclasses from effectively overriding it. Now, say you realize you don't need self in function C.f of class C, you have three two options:
Put it outside the class. But we just decided against this.
Do nothing new: while unused, still keep the self parameter.
Declare you are not using the self parameter, while still letting other C methods to call f as self.f, which is required if you wish to keep open the possibility of further overrides of f that do depend on some instance state.
Option 2 demands less conceptual baggage (you already have to know about self and methods-as-bound-functions, because it's the more general case). But you still may prefer to be explicit about self not being using (and the interpreter could even reward you with some optimization, not having to partially apply a function to self). In that case, you pick option 3 and add #staticmethod on top of your function.
Use #staticmethod for methods that don't need to operate on a specific object, but that you still want located in the scope of the class (as opposed to module scope).
Your example in test2.static_add_one wastes its time passing an unused self parameter, but otherwise works the same as test1.static_add_one. Note that this extraneous parameter can't be optimized away.
One example I can think of is in a Django project I have, where a model class represents a database table, and an object of that class represents a record. There are some functions used by the class that are stand-alone and do not need an object to operate on, for example a function that converts a title into a "slug", which is a representation of the title that follows the character set limits imposed by URL syntax. The function that converts a title to a slug is declared as a staticmethod precisely to strongly associate it with the class that uses it.
So I was looking at a certain class which has the following property function. However, the property method itself doesn't describe the procedure but instead calls another function to do so as follows:
class Foo():
#property
def params(self):
return self._params()
#property
def target(self):
return self._target()
def _params(self):
return print("hello")
def _target(self):
return print("world")
What I am trying to understand if it is some sort of pattern? I have seen a similar thing in another class as well where the method with property decorator simply calls another method of same name with underscore in the beginning.
Note: I do know what is property decorator but don't understand why this specific way of underscoring aims to achieve.
Effectively, the property is being used as a shortcut for calling a method with a fixed set of arguments. As a slightly different example, consider
class Foo():
#property
def params(self):
return self._params(1, "foo", True)
def _params(self, x, y, z):
...
f = Foo()
Now, f.params is a shortcut for f._params(1, "foo", True). Whether that is worth doing depends on whether _params is used for anything other than implementing the body of the params getter. If it isn't, there's little real point in writing code like this.
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.
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/
I wonder if there is a reasonable easy way to allow for this code (with minor modifications) to work.
class Info(object):
#attr("Version")
def version(self):
return 3
info = Info()
assert info.version == 3
assert info["Version"] == 3
Ideally, the code would do some caching/memoising as well, e.g. employ lazy attributes, but I hope to figure that out myself.
Additional information:
The reason why I want provide two interfaces for accessing the same information is as follows.
I’d like to have a dict-like class which uses lazy keys. E.g. info["Version"] should call and cache another method and transparently return the result.
I don’t think that works with dicts alone, therefore I need to create new methods.
Methods alone won’t do either, because there are some attributes which are easier to define with pure dictionary syntax.
It probably is not the best idea anyway…
If the attribute name (version) is always a lowercase version of the dict key ("Version"), then you could set it up this way:
class Info(object):
#property
def version(self):
return 3
def __getitem__(self,key):
if hasattr(self,key.lower()):
return getattr(self,key.lower())
If you wish the dict key to be arbitrary, then its still possible, though more complicated:
def attrcls(cls):
cls._attrdict={}
for methodname in cls.__dict__:
method=cls.__dict__[methodname]
if hasattr(method,'_attr'):
cls._attrdict[getattr(method,'_attr')]=methodname
return cls
def attr(key):
def wrapper(func):
class Property(object):
def __get__(self,inst,instcls):
return func(inst)
def __init__(self):
self._attr=key
return Property()
return wrapper
#attrcls
class Info(object):
#attr("Version")
def version(self):
return 3
def __getitem__(self,key):
if key in self._attrdict:
return getattr(self,self._attrdict[key])
I guess the larger question is, Is it a good interface? Why provide two syntaxes (with two different names) for the same thing?
Not trivially. You could use a metaclass to detect decorated methods and wrap __*attr__() and __*item__() appropriately.