2017-02-14 6 views
0

Ich bin neu in Python und habe eine Frage über Klassen und ihre Attribute in Python 2.6.Klassen in Python und definieren den Typ der Attribute

Lets sagen, dass ich eine Klasse Node wie dieses:

class Node: 
    x = int 
    y = int 
    neighbours = [] 
    discovered = bool 
    def __init__(self,x,y): 
     self.x = x 
     self.y = y 

    def setNeigbours(self,neighbours): 
     self.neighbours = neighbours 

    def addNeighbours(self,n): 
     if type(n) == list: 
      self.neighbours.extend(n) 
     else: 
      self.neighbours.append(n) 

    def isDiscovered(self): 
     return self.discovered 

    def setDiscovered(self,discovered): 
     self.discovered = discovered 

Und eine Klasse Graph wie folgt aus:

class Graph: 
    nodeList = Node 
    edgeList = Edge 

    def __init__(self,nodeList,edgeList): 
     self.edgeList = edgeList 
     self.nodeList = nodeList 

    def getNodes(self): 
     return self.nodeList 

    def setNodes(self,nodeList): 
     self.nodeList = nodeList 

    def addNode(self,n): 
     if type(n) == list: 
      self.nodeList.extend(n) 
     else: 
      self.nodeList.append(n) 

Wenn ich jetzt ein neues Diagramm erstellen und fügen Sie einige Knoten:

n1 = Node(0,0) 
n2 = Node(1,1) 
g = Graph([],[]) 
g.addNode(n1) 
g.addNode(n2) 

Ich würde Folgendes zu printerwarten:

for n in g.nodeList: 
    print type(n) 

Aber wenn ich es laufen, erhalte ich:

<type 'instance'> 
<type 'instance'> 

Gibt es eine Möglichkeit, Python zu sagen, dass die nodeList, eine Liste, die enthält nur Node -Elemente?

Antwort

0

Nichts davon ist, wie Sie Python schreiben; Es sieht stattdessen wie Java aus.

Sie müssen Attribute nicht auf Klassenebene "deklarieren"; Der einzige Grund, dies zu tun, ist die Verwendung von Werten, die für alle Instanzen gemeinsam genutzt werden, was Sie nicht tun, weil Sie sie sofort mit Instanzattributen überschreiben. Entferne diese Definitionen.

Es ist auch sehr unidiomatisch zu schreiben Getter-und Setter-Methoden, vor allem wenn sie nur das Attribut zurückgeben. Ihr Anrufcode sollte direkt auf die Attribute zugreifen.

In Bezug auf Ihre Frage, da Sie Python 2 [*] verwenden, müssen Ihre Klassen von Objekt erben. Wenn Sie das tun, werden Sie die richtigen Arten sehen:

class Graph(object): 
    ... 

g = Graph() 
type(g) # module.Graph 

(*) Anmerkung, die Sie wirklich nicht wirklich 2.6 verwenden müssen; Es ist veraltet und nicht unterstützt. Wenn Sie auf 2.x stecken, verwenden Sie mindestens 2,7; aber wirklich sollten Sie 3.x verwenden, das abgesehen von allem anderen Ihr ursprüngliches Problem behebt.

1

In der Tat gibt es, vorausgesetzt, Sie verwenden die neueste Version von Python (die zum Zeitpunkt des Schreibens 3.6.0 ist).

from typing import List 

class Graph: 
    nodeList: List[Node] 

Python selbst wird nicht wirklich etwas mit den Informationen tun, aber es gibt Typ-Prüfwerkzeuge für Python, die eine statische Analyse durchführen wird und Ihnen sagen, wenn Sie etwas anderes als ein Node in der Liste zu setzen versuchen, .

Bei älteren Versionen von Python 3 Sie etwas ähnliches mit einem fomatted Kommentar tun können, und die Typprüfung Werkzeugen werden dann in der Lage sein, die gleichen Kontrollen zu tun:

from typing import List 

class Graph: 
    nodeList # type: List[Node] 

All dies natürlich bietet nur optional statische Typprüfung bevor Sie das Programm ausführen. Sobald Ihr Code läuft, kümmert sich Python überhaupt nicht um die Arten von Objekten, solange sie die richtigen Methoden und Attribute haben: Wenn es wie eine Ente quakt, behandelt es Python als eine Ente.

Wenn Sie mehr über optionale statische Typprüfung in Python wissen, sehen http://mypy-lang.org/

Die Tatsache, dass das Drucken eine Instanz Ihrer Node Typ Sie <type 'instance'> gibt an, dass Sie eine Version von Python verwenden 2. Bitte beachten Sie Schalt überhaupt möglich auf eine neuere Version, wenn, aber zumindest, wenn Sie mit Python 2 stellen Sie sicher fortsetzen wollen, dass alle Ihre Objekte ableiten hiermit ausdrücklich von object:

class Node(object): 
    ... 

wenn Sie das tun die print-Anweisung zeigen du die c Mädel. Wenn Sie dies nicht tun, erhalten Sie altmodische Klassen aus den frühen Tagen von Python und Sie werden feststellen, dass Eigenschaften nicht korrekt mit ihnen funktionieren.

0

Es gibt keine Möglichkeit, den Typ in Python zu erzwingen, da Python dynamisch typisiert wird.

Eine mögliche Lösung besteht darin, den Instanztyp während der Laufzeit zu überprüfen.

Zuerst erben Ihre Klasse von object (dh ‚neuen Stils‘ Objekt):

class Node(object): 
    # your code here 

class Graph(object): 
    # your code here 

Und dann können Sie eine Typüberprüfung während der Laufzeit tun:

>>> g = Graph() 
>>> type(g) 
<class '__main__.Graph'> 
>>> isinstance(g, Graph) 
True 
0

Python dynamisch typisierte Sprache . Sie müssen Variablen nicht deklarieren, bevor Sie sie verwenden, oder ihren Typ deklarieren.

Sie können Dinge tun, wie folgt:

foo = 1 # this is an integer 
foo = "string" # this is a string 

Variable foo wird die Art der darin gespeicherten Wert.

In Python können Sie verschiedene Arten von Objekten in derselben Liste speichern. Wenn Sie nur einen Typ erzwingen möchten, der gespeichert werden soll, können Sie die Klasse list ableiten.

Verwandte Themen