我有下面的代码片段,可以创建一个音符并添加到笔记本中。
我的问题与全局变量last_id
更相关。当我将它声明为类变量时,即在Class Note中,我得到以下错误,但是当我在类之外声明时,我的代码工作正常。
以下是我的澄清:
last_id
? Error:
C:\Python27\Basics\OOP\formytesting>python notebook.py
Traceback (most recent call last):
File "notebook.py", line 38, in <module>
firstnote = Note('This is my first memo','example')
File "notebook.py", line 10, in __init__
last_id += 1
NameError: global name 'last_id' is not defined
code.py
import datetime
last_id = 0
class Note:
def __init__(self, memo, tags):
self.memo = memo
self.tags = tags
self.creation_date = datetime.date.today()
global last_id
last_id += 1
self.id = last_id
#global last_id
#last_id += 1
#self.id = last_id
def __str__(self):
return 'Memo={0}, Tag={1}, id={2}'.format(self.memo, self.tags,self.id)
class NoteBook:
def __init__(self):
self.notes = []
def add_note(self,memo,tags):
self.notes.append(Note(memo,tags))
def __iter__(self):
for note in self.notes:
yield note
if __name__ == "__main__":
firstnote = Note('This is my first memo','example')
print(firstnote)
Notes = NoteBook()
print("Adding a new note object")
Notes.add_note('Added thru notes','example-1')
Notes.add_note('Added thru notes','example-2')
for note in Notes.notes:
print(note.memo,note.tags)
for note in Notes:
print(note)
print("Adding a new note object----End")
答案 0 :(得分:10)
写作时
global last_id
在您的函数中,您没有创建新的全局变量。您正在做的是“不是创建新的局部变量并将其与名称last_id
相关联,而是将该名称与名称为last_id
的封闭范围中的预先存在的变量相关联”。
如果还没有名为last_id
的变量,那么global last_id
在您写入之前不会引用任何内容。但是,如果您写入它,它将在全局范围内创建。例如:
>>> def x():
... global X
... X = 1
...
>>> x()
# No error
>>> X
1 # X is now defined
>>> def y():
... global Y
... print Y
...
>>> y()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in y
NameError: global name 'Y' is not defined
答案 1 :(得分:9)
python比其他面向对象语言更明确地指出属性的来源;你可以有一个班级计数器,如下:
from itertools import count
class Foo(object):
last_id = count()
def __init__(self):
self.id = self.last_id.next()
你必须将last_id
称为self.last_id
,以便python知道查看实例(并且因为它不在那里,所以该类)。
答案 2 :(得分:2)
global
语句不绑定名称,它只是告诉编译器变量应该在全局范围内反弹。您仍必须自己执行初始绑定。
答案 3 :(得分:0)
Python使用变量的最内部范围,所以这个
def __init__(self, memo, tags):
....
global last_id
last_id += 1
可以工作,但是这个
def __init__(self, memo, tags):
....
last_id += 1
不会。
您可以将其重写为
class Note:
last_id = 0;
def __init__(self, memo, tags):
self.memo = memo
self.tags = tags
self.creation_date = datetime.date.today()
Note.last_id += 1
self.id = last_id