Reputation: 368
I want to do something a bit strange. I want to be able to access a class attribute that can be accessed as either a non-function or function:
class foo(object):
def __init__(self):
self.x = 99
def x(self, *args, **kwargs ):
print "x was called, args=%r, kwargs=%r" % (args, kwargs)
return( self.x ) # return something useful here...
f = foo()
print f.x # prints "x was called", 99
print f.x() # prints "x was called", 99
Upvotes: 0
Views: 443
Reputation: 1122502
No idea why you would want to do that, but here is one way, using the property
decorator:
class Foo(object):
@property
def x(self):
print "x was called"
return lambda: None
but this is completely nonsensical. It'll achieve what your example tries to do, but when you access Foo().x
a lambda function is returned that is otherwise useless.
If you are fine with returning instances of a custom class, then you can also give that custom class a __call__()
method that simply returns self
to give .x()
slightly more meaning:
class XReturnValue(object):
def __call__(self):
return self
class Foo(object):
@property
def x(self):
print "x was called"
return XReturnValue()
where XReturnValue
could be fleshed out more to actually mean something to the user of Foo.x
.
However, in Python callables (such as functions and methods) are objects in and of themselves. You can manipulate them, add attributes to them, assign them to different variables for later use, etc. To get their result you call them, but if you don't call them you can retrieve that reference to be re-used elsewhere. You should not try and circumvent that.
In other words, either stick with .x
being an attribute, a property
, or a method, but don't try to be all at once.
Upvotes: 3