First, there's no reason to assign None
to username
if you're just going to reassign it immediately after.
Second, if you want the method to be a static method, you can't give it a self
argument. And if you want a real static method, you have to declare it explicitly.
@staticmethod
def get_username():
if username is None:
...
Otherwise, you need an instance of the class (that self
) to call it on, and you don't have one yet.
In Python 3, any regular method acts like a static method when called on the class, like an instance method when called on an instance. So, if you're sure you're never going to want to call a.get_username()
on an instance a
, you can skip the decorator. But you still need to get rid of the self
parameter.
I think what you're actually trying to do is use a class variable to memoize the result of a static method. You can't do that, but you can use a class variable to memoize the result of a class method, which may be close enough. That would look like this:
class A:
username = None
@classmethod
def get_username(cls):
if cls.username is None:
try:
uname = os.environ["USER"]
except:
print("Couldn't find a user name")
else:
cls.username = uname
return cls.username
On the other hand, there's no good reason username has to be a class member. You can memoize by adding a member to the function, by passing a mutable default variable, or in various other ways which don't require infecting the class, and which allow you to leave get_username
as a static method instead of a class method.
But really, the best solution is to find a memoization library on PyPI, in ActiveState's recipe list, etc., so you can just write this:
class A:
@memoize
@staticmethod
def get_username():
try:
return os.environ["USER"]
except:
print("Couldn't find a user name")
return None
Again, you can drop the @staticmethod
if you're sure nobody's ever going to try to create an instance of A
and call get_username
on it.