5

クラスにインスタンスを保持するクラスに変数を追加しようとしています。以下は私のコードの短縮版です。

class Classy :
    def __init__(self) :
        self.hi = "HI!"
    # "CLASSIES" variable holds instances of class "Classy"
    CLASSIES = []
    for i in xrange(0,4) :
        CLASSIES.append(Classy())

コードを実行すると、次のエラーが発生します。

Traceback (most recent call last):
  File "classy.py", line 6, in Classy
    CLASSIES.append(Classy())
NameError: name 'Classy' is not defined

クラスのインスタンスをそのクラス内のクラス/静的変数に追加する別の方法はありますか?

4

4 に答える 4

2

これを行う最も簡単な方法は、クラスが作成された後、クラスが定義されており、したがって使用できるときに行うことです。

class Classy :
    CLASSIES = []

    def __init__(self) :
        self.hi = "HI!"

Classy.CLASSIES = [Classy() for _ in xrange(0,4)]

(ここでは、リストを作成する最も読みやすく効率的な方法であるため、便宜上リスト内包表記を使用しています)。

また、これが定数であることを意図している場合は、おそらくリストではなくタプルにする必要があることに注意してください。また、意図していない場合は、ALL_CAPS慣例により定数を意味する名前を使用しないでください。

于 2013-02-12T20:29:37.607 に答える
2

クラス本体は、クラスが作成される前に実行されます。したがって、存在する前にクラスをインスタンス化しようとしています。インスタンスをクラスにアタッチすることはできますが、クラス本体が終了した後にインスタンスを作成する必要があります。次に例を示します。

class Classy(object):
    def __init__(self):
        self.hi = "HI!"
    CLASSIES = []

for i in xrange(4):
    Classy.CLASSIES.append(Classy())

ただし、この効果的にグローバルなリストが実際に必要かどうか、クラス オブジェクトの一部にする必要があるかどうかについて、最初によく考えることをお勧めします。個人的には、このようなことはほとんどしません。

于 2013-02-12T20:31:53.093 に答える
2

あなたはそれを手に入れたいようです:

class Classy :
    CLASSIES = []
    def __init__(self) :
        self.hi = "HI!"
        Classy.CLASSIES.append(self)

for i in xrange(4):
    Classy()

for x in  Classy.CLASSIES:
    print x

結果

<__main__.Classy instance at 0x011DF3F0>
<__main__.Classy instance at 0x011DF440>
<__main__.Classy instance at 0x011DF418>
<__main__.Classy instance at 0x011DF2B0>

編集

Lattyware のコードでは次の点に注意してください。

class Classy :
    CLASSIES = []
    idC = id(CLASSIES)
    def __init__(self) :
        self.hi = "HI!"
        #Classy.CLASSIES.append(self)


Classy.CLASSIES = [Classy() for _ in xrange(0,4)]

print Classy.idC
print id(Classy.CLASSIES)
print 'Classy.idC==id(Classy.CLASSIES) :',Classy.idC==id(Classy.CLASSIES)

結果

18713576
10755928
Classy.idC==id(Classy.CLASSIES) : False

delnan'code の for ループでは現れません。

ただし、修正するのは簡単です。
書き込み
Classy.CLASSIES[:] = [Classy() for _ in xrange(0,4)]
または
Classy.CLASSIES.extend(Classy() for _ in xrange(0,4))
その代わりに
Classy.CLASSIES = [Classy() for _ in xrange(0,4)]
、何が必要かによって異なります。

編集2

メソッドは、通常の関数と同じ方法でグローバル名を参照できます。メソッドに関連付けられたグローバル スコープは、その定義を含むモジュールです。(クラスがグローバル スコープとして使用されることはありません。)

http://docs.python.org/2/tutorial/classes.html#class-definition-syntax

クラスには、ディクショナリ オブジェクトによって実装される名前空間があります。クラス属性参照は、このディクショナリ内のルックアップに変換されます。たとえば、次のように変換されますC.xC.__dict__["x"]

http://docs.python.org/2/reference/datamodel.html#new-style-and-classic-classes

class Classy :
    CLASSIES = []

print '"CLASSIES" in globals()',"CLASSIES" in globals()
print '"CLASSIES" in Classy.__dict__ ==',"CLASSIES" in Classy.__dict__

結果

"CLASSIES" in globals() False
"CLASSIES" in Classy.__dict__ == True

Delnan、CLASSIESがグローバルであるというふりをどのように続けますか??
Lattyware との議論で何か誤解していましたか?

于 2013-02-12T21:00:05.590 に答える
1

クラス自体は、クラス ブロックの実行が終了するまで定義されないため、独自の定義内でクラスを使用することはできません。

クラス デコレータまたはメタクラスを使用して、クラスの作成後に目的のクラス変数を追加できます。デコレータを使用した例を次に示します。

def addClassy(cls):
    cls.CLASSIES = [cls() for a in xrange(4)]
    return cls

@addClassy
class Classy(object):
    pass

>>> Classy.CLASSIES
0: [<__main__.Classy object at 0x000000000289A240>,
 <__main__.Classy object at 0x000000000289A518>,
 <__main__.Classy object at 0x000000000289A198>,
 <__main__.Classy object at 0x000000000289A208>]
于 2013-02-12T20:29:44.753 に答える