I have following code:
class Foo(object):
def __init__(self):
baz=self.bar(10)
@staticmethod
def bar(n):
if n==0:
return 'bar'
else:
return bar(n-1)
bar() as a recursive function it needs reference to itself. However, bar() is inside a class, and calling return bar(n-1)
will not work, invoking NameError: global name 'bar' is not defined
. How can I deal with this kind of situation? Should I change bar() to a class or instance method, allowing access to self
or cls
?
A static method (or static function) is a method defined as a member of an object but is accessible directly from an API object's constructor, rather than from an object instance created via the constructor.
staticmethods can be used when the code that belongs to a class doesn't use the object itself at all. Python doesn't have to instantiate a bound method for each object we instantiate. Bound methods are objects too, and creating them has a cost. Having a static method avoids that.
Yes, it most certainly is. When you apply static to a function, it's not the same as a static variable within a recursive function (which is a problem if it's used in the calculations).
A static method has two main purposes: For utility or helper methods that don't require any object state. Since there is no need to access instance variables, having static methods eliminates the need for the caller to instantiate the object just to call the method.
You can refer to bar
by prefixing it with the class name:
class Foo(object):
def __init__(self):
baz=self.bar(10)
@staticmethod
def bar(n):
if n==0:
return 'bar'
else:
return Foo.bar(n-1)
Static methods are nothing but regular functions contained within the namespace of a class after all.
Alternatively, define bar
as a regular function instead:
def bar(n):
if n==0:
return 'bar'
else:
return bar(n-1)
class Foo(object):
def __init__(self):
baz=bar(10)
which avoids the whole issue altogether.
An alternative to using a class method or calling the class by name (as shown by others) is to use a closure to hold the reference to the function:
class Foo(object):
def bar():
def bar(n):
if n == 0:
return "bar"
return bar(n-1)
return bar
bar = staticmethod(bar())
The (minor) advantage is that this is somewhat less susceptible to breaking when names change. For example, if you have a reference to Foo.bar
inside bar
, this relies on Foo
continuing to be a global name for the class that bar
is defined in. Usually this is the case but if it isn't, then the recursive call breaks.
The classmethod
approach will provide the method with a reference to the class, but the class isn't otherwise needed in the method, which seems inelegant. Using the closure will also be marginally faster because it isn't doing an attribute lookup on each call.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With