J'ai le code ci-dessous qui crée une note et l'ajoute à un cahier.
Ma question concerne davantage la variable globale last_id
. Lorsque je le déclare en tant que variable de classe, c'est-à-dire dans Class Note, j'obtiens le message d'erreur suivant, mais lorsque je déclare en dehors de la classe, mon code fonctionne correctement.
Voici mes clarifications:
last_id
lorsque je le déclare en tant que variable globale dans ma fonction?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 __== "__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")
Quand tu écris
global last_id
Dans votre fonction, vous ne créez pas de nouvelle variable globale. Vous dites "au lieu de créer une nouvelle variable locale et de l'associer au nom last_id
, associez plutôt ce nom à une variable préexistante de l'étendue englobante qui porte le nom last_id
"
S'il n'y a pas déjà une variable appelée last_id
, alors global last_id
ne fait référence à rien avant que vous n'y écriviez. Cependant, si vous y écrivez, il sera créé dans la portée globale. Par exemple:
>>> 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
python est un peu plus explicite sur l'origine des attributs que d'autres langages orientés objet. vous pouvez avoir un compteur de niveau de classe, comme ceci:
from itertools import count
class Foo(object):
last_id = count()
def __init__(self):
self.id = self.last_id.next()
vous devez faire référence à last_id
en tant que self.last_id
, afin que python sache regarder sur l'instance (et puisqu'elle n'est pas déjà présente, la classe).
L'instruction global
ne lie pas un nom, elle indique simplement au compilateur que la variable doit être rebondie dans la portée globale lorsque cela se produit. Vous devez toujours effectuer la liaison initiale vous-même.
Python utilise la portée la plus interne de la variable, donc ceci
def __init__(self, memo, tags):
....
global last_id
last_id += 1
travaillera mais cela
def __init__(self, memo, tags):
....
last_id += 1
ne sera pas.
Vous pouvez le réécrire comme
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