まず、直後に再割り当てNone
する場合は、に割り当てる必要はありません。username
次に、メソッドを静的メソッドにしたい場合、self
引数を与えることはできません。実際の静的メソッドが必要な場合は、明示的に宣言する必要があります。
@staticmethod
def get_username():
if username is None:
...
それ以外の場合は、それを呼び出すクラスのインスタンス ( that self
) が必要ですが、まだありません。
Python 3 では、通常のメソッドは、クラスで呼び出されると静的メソッドのように機能し、インスタンスで呼び出されるとインスタンス メソッドのように機能します。a.get_username()
したがって、インスタンスを呼び出したくないことが確実な場合はa
、デコレータをスキップできます。ただし、パラメーターを削除する必要がありself
ます。
あなたが実際にやろうとしているのは、クラス変数を使用して静的メソッドの結果をメモすることだと思います。それはできませんが、クラス変数を使用してクラスメソッドの結果をメモすることはできます。これは十分に近いかもしれません。それは次のようになります。
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
一方、ユーザー名がクラスのメンバーでなければならない正当な理由はありません。関数にメンバーを追加する、変更可能なデフォルト変数を渡す、またはクラスに感染する必要がget_username
なく、クラスメソッドではなく静的メソッドとして残すことができるその他のさまざまな方法でメモ化できます。
しかし、実際には、最善の解決策は、PyPI や ActiveState のレシピ リストなどでメモ化ライブラリを見つけることです。したがって、次のように記述できます。
class A:
@memoize
@staticmethod
def get_username():
try:
return os.environ["USER"]
except:
print("Couldn't find a user name")
return None
繰り返しますが、@staticmethod
誰も のインスタンスを作成してA
呼び出しようとしないことが確実な場合は、 を削除できますget_username
。