0

Python を学習していて、連結リスト クラスの作成に取り組んでいるときに、いくつかの問題に遭遇しました。これは単なるクイック ノードとダーティ ノード クラスです。Java では、プライベート Node next とプライベート int val をダウンさせますが、グローバルは Python のいとことしか知りませんでした。これはどのように見えますか?

#class Node class

class Node(object):
    global next
    global val
    def __init__(self):
        next
        val
    def setNext(self, aNext):
        self.next = aNext
    def getNext(self):
        return self.next
    def setVal(self, aVal):
        self.val = aVal
    def getVal(self):
        return self.val

次に、別のクラスで Node を使用しようとしました

from Node import *
head = Node()

未定義変数のエラーが発生しました。Python を初めて使用する単純な質問で申し訳ありません。助けに感謝します。

4

4 に答える 4

7

私はこれを次のように実装します:

class Node(object):
    def __init__(self, next=None, val=None):
        self.next = next
        self.val = val

それでおしまい。ゲッターもセッターもありません - Python はそれらを使用しません。代わりに、基本的な属性参照ロジックから離れる必要がある場合は、プロパティにリファクタリングします。

次に、値またはサクセサの有無にかかわらずノードを作成できます。

tailnode = Node()
tailnode.val = 'foo'
midnode = Node(val='bar')
midnode.next = tailnode
headnode = Node(val='baz', next=midnode)
于 2013-09-25T21:45:20.443 に答える
1

Python で本当にプライベート変数が必要な場合は、プライベート変数は必要ありません。Peter DeGlopper の回答を読む必要があります。

それでも、本当に、本当に Python でプライベート変数が必要な場合は…まあ、それらを持つことはできません。しかし、「協調的にプライベートな」変数を持つことができます — 探しに行かなければ誰も見つけられず、インタープリターで物事を内省するときに画面が乱雑になることのない変数など、そして最も重要なのは、その Python プログラマー慣例により、触れてはならないことを知っています。名前をアンダースコアで始めるだけです。


ただし、いくつかの理由により、コードはメンバー変数をまったく作成していません。

まず、global変数を宣言または定義しません。それが行うのは、Python に「この変数を後で見たときに、それがローカルかグローバルかを判断するために通常のルールを使用せず、常にグローバル コピーを使用する」ことです。変数のどこかに値を代入する必要があります。それ以外の場合は、NameError.

次に、class定義で割り当てる変数はクラスメンバーです。Java の静的メンバーに似ていますが、同一ではありません。各クラス メンバーは、クラスのすべてのインスタンスによって共有されます。それはあなたがここで望んでいることではありません。それぞれNodeが独自の個別のvalandを持っているはずでありnext、1 つを他のすべての s と共有するのではありませんNodeよね?

通常のインスタンス メンバー変数は、クラスのメソッド内から、または外部から、常にドット構文を介してアクセスされます。self.foospam.foo

それで、あなたはそれらをどこで宣言しますか?あなたはそうしない。Python は何も宣言しません。いつでも新しいメンバーをオブジェクトに追加できます。インスタンス メンバーの標準セットを作成する通常の方法は、__init__メソッド内にあります。

class Node(object):
    def __init__(self):
        self._next = None
        self._val = None
    def setNext(self, aNext):
        self._next = aNext
    def getNext(self):
        return self._next
    def setVal(self, aVal):
        self._val = aVal
    def getVal(self):
        return self._val

しかし実際には、セッターにそれらを作成させることができます。そうすれば、誰かが最初に電話をかけgetNextずに電話をかけた場合にエラーをキャッチできますsetNext(これは違法だと思います)。

class Node(object):
    def setNext(self, aNext):
        self._next = aNext
    def getNext(self):
        return self._next
    def setVal(self, aVal):
        self._val = aVal
    def getVal(self):
        return self._val

または、代わりに、構築時に有効な値でオブジェクトを初期化するようユーザーに強制します。

    def __init__(self, next, val):
        self._next = next
        self._val = val

繰り返しますが、そもそも Python でセッターとゲッターを使用する正当な理由はありません。

したがって、クラスの最も単純な実装は次のとおりです。

class Node(object):
    pass

最も Pythonic は次のとおりです。

class Node(object):
    def __init__(self, next, val):
        self.next = next
        self.val = val

…お気づきでしょうが、これは Peter DeGlopper の答えであり、冒頭で述べたように、おそらくあなたが望むものです。:)

于 2013-09-25T22:46:54.327 に答える
1

「global val」/「global next」は必要ありません..それは間違いでもあります。代わりに書くだけ val = None next = None

でそれらを開始します__init__()

つまり、クラスの最初の行は次のようになります。

class Node(object):
    # You can choose whether to initialize the variables in the c'tor or using your setter methods
    def __init__(self, val=None, next=None):
        self.next = next
        self.val = val
于 2013-09-25T21:44:10.713 に答える
0

Python は実際にはプライベート変数を使用しません。

次のようなものが最適です。

class Node(object):
    def __init__(self):
        self.val = None
        self.next = None

次に、次のようにノードを作成して設定します。

>>> node = Node()
>>> node.val = 5
>>> node2 = Node()
>>> node2 = 1
>>> node.next = node2
>>> node.next.val
1

でノードを作成する場合はNode(5, Node(1))、次を使用します。

class Node(object):
    def __init__(self, value=None, next=None):
        self.value = value
        self.next = next
于 2013-09-25T21:46:35.763 に答える