1

クラス スコープ内で動的属性を宣言することは「Python のやり方」ではないと言われましたが、その理由がわかりません。誰かが私にこれを説明したり、これがなぜ悪いことなのかについていくつかのドキュメントを教えてもらえますか? 正直なところ、自己文書化コードに関しては、これは良い習慣だと思いました。

例:

class ClassA(object):
    user_data = {}

    def set_user(self):
        self.user_data['username'] = 'fred'

これを使用しない唯一の理由は、属性が静的であることです (したがって、誤解を招く可能性があります)。

4

4 に答える 4

3

コメントで、「まあ、各インスタンスには異なる変更可能な user_data があります」と言います。いいえ、それはしません。ClassA のすべてのインスタンスは、同じ user_data ディクショナリを共有します。

>>> class ClassA(object):
...     user_data = {}
...     def set_user(self, name):
...         self.user_data['name'] = name
...
>>> a1 = ClassA()
>>> a1.set_user('fred')
>>> a1.user_data
{'name': 'fred'}
>>>
>>> a2 = ClassA()
>>> a2.user_data
{'name': 'fred'}
>>> a2.set_user('barney')
>>> a2.user_data
{'name': 'barney'}
>>>
>>> a1.user_data
{'name': 'barney'}
>>>
>>> a1.user_data is a2.user_data
True

これは、何かが Pythonic であるかどうかの問題ではありません。必要に応じて動作するコードを書くことが問題です。

于 2013-02-11T16:10:30.773 に答える
1

示されているコードでuser_dataは、動的属性ではありません(クラス インスタンスで「動的に」作成されません)。これは、私が信じている他の言語の「静的」属性によく似たクラス属性です。これは、クラスが読み取られて初期化されるときにクラスで宣言された属性であることを意味します。これには、すべてのインスタンスが を介して同じオブジェクトにアクセスできるという副作用/利点がありますself.whatever

言い換えると:

class Foo(object):
    whatever = {}
    def __init__(self):
        print self.whatever is Foo.whatever

常に印刷されますTrue。もちろん、whateverインスタンスに別の属性を追加することで、この動作を変更できます。

class Bar(object):
     whatever = {}
     def __init__(self):
         self.whatever = {}
         print self.whatever is Bar.whatever

ではFoo、アイテムを追加するとfoo_instance.whatever['foo'] = 'bar'foo_instance2その変更も表示されますが、の場合はそうではありませんBar

于 2013-02-11T15:51:52.250 に答える