I'm new to Python and have a question about Classes and their attributes in Python 2.6.
Lets say I have a Class Node
like this:
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
And a Class Graph
like this:
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)
If I now create a new Graph and add some Nodes:
n1 = Node(0,0)
n2 = Node(1,1)
g = Graph([],[])
g.addNode(n1)
g.addNode(n2)
I would expect the following to print
<Type 'Node'>
:
for n in g.nodeList:
print type(n)
But when I run it, I get:
<type 'instance'>
<type 'instance'>
Is there a way, to tell Python, that the nodeList
, is a list, which only contains Node
-Elements?
Indeed there is, provided you are using the latest version of Python (which at the time of writing is 3.6.0).
from typing import List
class Graph:
nodeList: List[Node]
Python itself won't actually do anything with the information, but there are type-checking tools for Python which will perform a static analysis and tell you if you attempt to put something other than a Node
in the list.
With older versions of Python 3 you can do something similar with a fomatted comment and the typechecking tools will then be able to do the same checks:
from typing import List
class Graph:
nodeList # type: List[Node]
All of this of course only provides optional static typechecking before you run the program. Once your code is running Python won't care at all about the types of objects so long as they have the right methods and attributes: if it quacks like a duck Python will treat it as a duck.
If you want to know more about optional static typechecking in Python see http://mypy-lang.org/
The fact that printing an instance of your Node
type gives you <type 'instance'>
indicates that you're using some version of Python 2. Please consider switching to a newer version if at all possible, but at the very least if you want to continue with Python 2 make sure that all of your objects explicitly derive from object
:
class Node(object):
...
If you do that the print statement will show you the class. Failing to do this gives you old-style classes from the very early days of Python and you'll find things like properties don't work correctly with them.
None of this is how you write Python; it looks like Java instead.
You do not need to "declare" attributes at class level; the only reason to do that is to use values that are shared across all instances, which you are not doing because you immediately overwrite them with instance attributes. Remove those definitions.
It is also very unidiomatic to write getter and setter methods, especially if they just return the attribute. Your calling code should access the attributes directly.
As to your question, since you are using Python 2 [*] your classes must inherit from object. If you do that, you will see the correct types:
class Graph(object):
...
g = Graph()
type(g) # module.Graph
(*) note, you really really must not use 2.6; it is out of date and unsupported. If you are stuck on 2.x at least use 2.7; but really you should use 3.x, which apart from anything else fixes your original issue.
There's no way to enforce type in Python because Python is dynamically typed.
A possible solution is to check the instance type during the runtime.
First, inherit your class from object
(ie 'new style' object):
class Node(object):
# your code here
class Graph(object):
# your code here
And then you can do a type checking during runtime:
>>> g = Graph()
>>> type(g)
<class '__main__.Graph'>
>>> isinstance(g, Graph)
True
Python is dynamically typed language. You do not need to declare variables before using them, or declare their type.
You can do stuff like this:
foo = 1 # this is an integer
foo = "string" # this is a string
Variable foo
will have the type of the value stored in it.
In Python you can store different types of objects in the same list, if you want to enforce only one type to be stored you can subclass the builtin list
class.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.