まず、名前UserClass
をUser
(クラスであることはわかっています) および(クラス内にあるUserID
ため、「ユーザー」ビットを繰り返す必要はありません。Python スタイルでは小文字をお勧めします) および(同上) に変更します。Python スタイルのガイドラインについては、PEP 8を参照してください。id
User
__user_id_counter
__id_counter
それでは、出発点は次のとおりです。
class User(object):
__id_counter = 0
def __init__(self, id=None) :
self.id = self.__id_counter if id is None else id
__id_counter += 1
myuser = User()
myuser2 = User()
myuser3 = User()
__init__
現在、二重の先頭のアンダースコア ( andのような二重の末尾のアンダースコアなし__metaclass__
) は特別であり、クラス プライベート変数の実装に使用されます。詳細については、Python マニュアルのプライベート変数を参照してください。これは、いわゆる「ネーム マングリング」を引き起こします。クラス全体__id_counter
で名前が変更されたままになります。_User__id_counter
これは便利でもあり、危険でもあります。この場合、おそらく必要ないと思います。
これにより、サブクラスで問題が発生する可能性があります。
class SpecialUser(User):
def __init__(self):
self.__id_counter
これで、SpecialUser()
がトリガーされAttributeError: 'SpecialUser' object has no attribute '_SpecialUser__id_counter'
ます。
そこで問題は、サブクラスに同じID カウンターを持たせたいのか、それとも独自のID カウンターを持たせたいのかということです。
それらに同じID カウンターを持たせたい場合は、 を使用しますUser.__id_counter
。またはと一緒に使用しないでください。これは、インスタンスに対して に設定され、この時点から独自のものを使用するため、必要なものとはかけ離れています。self.__class__.__id_counter
type(self).__id_counter
+= 1
SpecialUser
SpecialUser._User__id_counter
User._User__id_counter + 1
SpecialUser
_User__id_counter
それらに独自のID カウンターを持たせたい場合は、_id_counter
ではなくを使用することから始め__id_counter
てください。
いくつかの方法があります。
メタクラスを使用して、各クラスに独自のカウンター変数を与えます (現時点で書くのが面倒なトピックよりも高度なトピックです。必要に応じて詳細を尋ねてください)。
_id_counter = 0
各クラス定義に一行入れます。(そうしないと、ID の開始点で問題が発生します。たとえば をたくさん作成すると、.ではなくUser(), User(), SpecialUser(), User(), SpecialUser(), SpecialUser(), User()
(それぞれ) の ID を持つことになります。0, 1, 2, 2, 3, 4, 3
0, 1, 0, 2, 1, 2
ここで名前マングリング アプローチを使用することで生じる追加の非効率性は、サブクラスに複数のカウンター_User__id_counter
( 、_SpecialUser__id_counter
など) が含まれることです。