7

我有下面的一段代码,它创建一个笔记并添加到笔记本中。

我的问题与全局变量更相关last_id。当我将它声明为类变量时,即在类注释中,我收到以下错误,但是当我在类之外声明时,我的代码工作正常。

以下是我的澄清:

  1. 为什么它不接受类变量。
  2. 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")    
4

4 回答 4

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
于 2012-08-08T20:45:18.167 回答
9

与其他面向对象的语言相比,python 对属性的来源更加明确;您可以有一个班级级别的计数器,如下所示:

from itertools import count

class Foo(object):
    last_id = count()

    def __init__(self):
        self.id = self.last_id.next()

您必须引用last_idas self.last_id,以便 python 知道查看实例(并且因为它不存在,所以类)。

于 2012-08-08T20:47:09.923 回答
2

global语句不绑定名称,它只是告诉编译器该变量在发生时应该在全局范围内重新绑定。您仍然必须自己执行初始绑定。

于 2012-08-08T20:44:52.993 回答
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
于 2012-08-08T20:47:00.737 回答