0

私は 3 か月間 Python を勉強してきましたが、Google を使用しても解決できなかった質問がありますが、幸運にもここで簡単に説明することができます。

私は var_class モジュールを持っています:

#var_class.py

class A(object):
    def __init__(self, x):
        self.x = x+2

zz = A(10)

class B():
    b = 0    
    def __init__(self):
        pass
    def update(self):
        B.b = zz.x

そしてメインプログラムには次のものがあります:

#main.py

from var_class import *

b_class = B()
b_class.b        # I get 0 as expected
zz = A(100)
b_class.update()
b_class.b        # Instead of 102, I get 12 unexpectedly

私の目標は、すべてのデータ入力に対して "zz" を頻繁に変更し、クラス変数 'b' を更新することです。var_class.py に zz = A(10) を記述した理由は、それをインポートすると、モジュール ' 「var_class」に「クラス B」の「zz」がありません。「グローバル名 zz が定義されていません」というエラーが発生します。

しかし、今こう書いていると、値「10」がクラスに引っかかっているようで、メインプログラムで変更できません。これを克服する方法がわかりません。助けてくれてありがとう。

答え:

alKid が最初に回答全体を書きました。alexvassel と C 氏にも感謝しなければなりません。彼らに感謝する方法があるかどうか知りたいです。他の人が知識を手伝ってくれました。また、たくさん感謝しています。

4

6 に答える 6

1

分かりやすい: それはできません。あなたはvar_classモジュールの中にいるのでzzA(10).

パラメータとしてzzを渡すのはどうですか?このような!

class A(object):
    def __init__(self, x):
        self.x = x+2

zz = A(10)

class B():
    b = 0    
    def __init__(self):
        pass
    def update(self, zz):
        B.b = zz.x

お役に立てれば!

于 2013-10-09T13:06:27.653 に答える
1

Python ランタイムは、名前空間によって変数を検索します。名前空間はスコープのようなものです。Bb = zz.xが実行されると、ランタイムは最初にローカルの名前空間 (関数の名前空間 -- 更新) を検索しますが、 zz は見つかりませ。次に、モジュール空間 (var_class) に移動し、変数を取得して検索を停止します。

Python 名前空間の検索順序:
1. ローカル名前空間、関数スコープ
2. グローバル名前空間、モジュール スコープ
3. 組み込み名前空間

グローバル変数を使用しない方がよいでしょう。

あなたのコードは次のようになります:

class B():
b = 0    
def __init__(self):
    pass
def update(self, zz):
    B.b = zz.x
于 2013-10-09T13:08:39.493 に答える
0

それは範囲の問題です!main.py で zz = A(100) を使用しています。しかし、b_class.update() を呼び出すと、b_class は「zz」という名前の「some2 変数」を取得する必要があります。利用可能な変数は、class.py で定義した変数です。これにはまだ値 A(10) があります。 !!!

これを回避するには、さまざまなオプションがあります。

  • 汚いハック(ただし、ソリューションに最も近い)は、global変数を定義して ist を使用することです(このアプローチの詳細については、「python globals」をグーグルで検索してください)。
  • A (または Ax) を「更新」メソッドに渡すことをお勧めしますb_class.update(A.x)。これにより、グローバルが回避され、読みやすくなります。もちろん、新しいパラメータに合わせて B.update を調整する必要があります。
于 2013-10-09T13:04:54.487 に答える
0

モジュールから変数をインポートすると、元の変数ではなく、変数のコピーが取得されます。オリジナルに直接書き込む必要があります。

from a.b import c
from a.b.c import var

a.b.c.var = 1

var = 2

a.b.c.var
1
var
2

編集:したがって、より正確には、Pythonではメモリ内にオブジェクトがあり、オブジェクトの名前があります。モジュールをインポートすると、2 つの別々の名前が作成されますが、どちらも同じオブジェクトを指しています。つまり、同じオブジェクトへの参照を持っています。これは、インポートをまったく必要としない以下のコードと非常によく似ています。

>>> a = 4
>>> b = a
>>> b
4
>>> a
4
>>> b = 'something different'
>>> b
'something different'
>>> a
4

b を変更しても a が変更されないのはなぜですか? シーケンスは次のようになります。まず、オブジェクト (4) を作成し、名前 'a' をそのオブジェクトに向けます。次に、「b」という名前を作成し、同じオブジェクトを指します。したがって、これらの名前を検索すると、同じオブジェクトが返されます。ここで、戻って名前 'b' を別のオブジェクトである文字列に向けます。'a' が指しているオブジェクトはまだ存在し、変更されていません。

新しいユーザーは、リストのようなオブジェクトを使用して、これとは逆につまずくことがよくあります。

>>> a = [1,2,3,4,5]
>>> b = a
>>> b
[1,2,3,4,5]
>>> a
[1,2,3,4,5]
>>> b.append(6)
>>> b
[1,2,3,4,5,6]
>>> a
[1,2,3,4,5,6]
>>> b = b[1:3]
>>> b
[2,3]
>>> a
[1,2,3,4,5,6]

何が起きてる?まず、リスト オブジェクトを作成し、それから名前 'a' をポイントします。次に、「b」という名前を作成し、同じオブジェクトを指します。したがって、'a' と 'b' はどちらも同じリストを指しています。次に、参照 b を使用してオブジェクトを取得し、変更します。この場合、「b」が指すものを変更していないことに注意してください。参照を取得してから、それが指すオブジェクトを直接変更しています。したがって、この場合、'a' と 'b' の両方が変更を認識し、両方とも変更されたオブジェクトを指します。次に、スライスを抽出し、それを 'b' に割り当てます。さて、これは実際に新しいオブジェクトを作成し、'b' をそのオブジェクトに向けます。'b' はもはや元のオブジェクトを指していません。だから今 'a' と 'b'

インポート ケースは、この特殊なケースにすぎません。

于 2013-10-09T13:06:58.813 に答える
-1

多分あなたはこれを行うことができます

class B():
    b = 0    
    def __init__(self):
        pass
    def update(self,value):
        self.b =self.b+value
于 2013-10-09T13:05:46.137 に答える