How can I access qux
inside methods? Do I really have to define it again inside the body of foo()
, or is there a way to import it from self
?
class Baz(object):
qux = lambda x : x + '_quux'
def foo(self, bar=qux('fred')):
print bar
print qux('waldo')
# NameError: global name 'qux' is not defined
print Baz.qux('waldo')
# TypeError: unbound method <lambda>() must be called with Baz instance as first argument (got str instance instead)
print Baz.qux(self, 'waldo')
# TypeError: <lambda>() takes exactly 1 argument (2 given)
print self.qux('waldo')
# TypeError: <lambda>() takes exactly 1 argument (2 given)
If you want to be able to access a method off the class then you must use classmethod
or staticmethod
.
class Baz(object):
qux = staticmethod(lambda x : x + '_quux')
But don't do that.
qux
is being treated like an instance method, because that's the default handling for class members that look like functions (more specifically, Baz.qux
has a __get__
that is implicitly called to "bind" the first parameter to the instance, when you look it up via an instance). However, you haven't provided a self
parameter at the start. Accordingly, baz
gets bound to the x
lambda parameter instead.
There is nothing magical about the name 'self' in Python; it's just convention. Method binding always works by binding to the first argument of a function.
You can see this for yourself, if you're clever:
class Baz(object):
qux = lambda x: x + '_quux'
def foo(self): return self.qux()
Baz().foo() # TypeError: unsupported operand type(s) for +: 'Baz' and 'str'
# because after binding Baz() to 'x', we get Baz() + '_quux'
One solution is to explicitly make qux
a staticmethod
, as in Sven Marnach's answer. (You can also make it a classmethod
, which is a Python-specific concept that's more powerful; staticmethod
more closely parallels the behaviour of the static
keyword in languages like Java.) Note that, as in Java, you can also access the staticmethod
as self.qux
within foo
. This works by replacing the normal __get__
machinery for functions with new machinery installed by staticmethod
.
Another solution is to provide for the self
parameter in the lambda parameters. This is useful if you actually don't want "static" behaviour (i.e. will need to actually do something with self
) - but it looks very much as if you do. Just for completeness, this would look like:
qux = lambda self, x: x + '_quux'
def foo(self):
return self.qux('foo')
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