全局变量声明Python

时间:2012-08-08 20:39:39

标签: python global-variables

我有下面的代码片段,可以创建一个音符并添加到笔记本中。

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

以下是我的澄清:

  1. 为什么不接受类变量。
  2. 当我在函数中将其声明为全局变量时,为什么需要定义last_id
  3. 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 个答案:

答案 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