Python 全局变量声明

Python 全局变量声明,python,global-variables,Python,Global Variables,我有下面的一段代码,可以创建一个便条并添加到笔记本中 我的问题与全局变量last\u id更相关。当我将其声明为类变量(即类内注释)时,会出现以下错误,但当我在类外声明时,我的代码工作正常 以下是我的澄清: 为什么它不接受类变量 当我在函数中将其声明为全局变量时,为什么需要定义last\u id 错误: C:\Python27\Basics\OOP\formytesting>python notebook.py Traceback (most recent call last): Fi

我有下面的一段代码,可以创建一个便条并添加到笔记本中

我的问题与全局变量
last\u id
更相关。当我将其声明为类变量(即类内注释)时,会出现以下错误,但当我在类外声明时,我的代码工作正常

以下是我的澄清:

  • 为什么它不接受类变量
  • 当我在函数中将其声明为全局变量时,为什么需要定义
    last\u id
  • 错误:

    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
    
    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")    
    

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

    当您编写

    global last_id
    
    在函数内部,您没有创建新的全局变量。您要做的是说“与其创建一个新的局部变量并将其与名称
    last\u id
    关联,不如将该名称与包含范围内具有名称
    last\u id
    的预先存在的变量关联。”

    如果还没有名为
    last\u id
    的变量,则
    global last\u 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
    
    >>def x():
    ...     全球X
    ...     X=1
    ... 
    >>>x()
    #无误
    >>>X
    现在定义了1#X
    >>>定义y():
    ...     全局Y
    ...     打印Y
    ... 
    >>>y()
    回溯(最近一次呼叫最后一次):
    文件“”,第1行,在
    文件“”,第3行,y方向
    NameError:未定义全局名称“Y”
    
    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
    

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

    from itertools import count
    
    class Foo(object):
        last_id = count()
    
        def __init__(self):
            self.id = self.last_id.next()
    

    您必须将
    last\u id
    称为
    self.last\u id
    ,以便python知道如何查看实例(因为实例还不存在,所以类也不存在)。

    这是唯一与实际问题相关的答案。所有其他答案要么完全错了,要么回答了另一个问题。@SvenMarnach——我的答案和这个答案很接近,所以很好奇——做Foo.last_id和self.last_id有问题吗?@dfb:一个缺点是,
    Foo.last_id
    只有在
    type(self)=Foo
    时才是正确的,但可能是
    type(self)!=Foo和isinstance(self,Foo)
    ,如果Foo是子类,并且子类提供了自己的
    最后一个id
    。使用
    type(self.last\u id
    )可能会稍微好一点,但这对我来说似乎有点苛刻。如果我使用
    global last\u id
    ,然后使用
    last\u id=1
    ,效果会很好。短语“如果还没有变量
    X
    ,那么
    global X
    不表示任何内容”是错误的。变量可以在以后定义。@tmoreau谢谢你说得对。我已经更新了我的答案。
    global x
    声明是否需要在我们使用它的每个函数中进行?