Maison > Questions et réponses > le corps du texte
Il existe une telle fonction :
def outside():
x=[]
print(id(x))
def inside():
print(id(x))
x[:]=[1,2,3]
print(id(x))
inside()
print(id(x))
print(x)
Aucun problème n'est survenu après l'appel, sortie :
140560473157960
140560473157960
140560473157960
140560473157960
[1, 2, 3]
Mais remplacez le x à l'intérieur par une chaîne, comme suit :
def outside():
x='outside'
print(id(x))
def inside():
print(id(x))
x='inside'
print(id(x))
inside()
print(id(x))
print(x)
Lorsque l'appel est refait, cela devient :
140560473762872
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 8, in outside
File "<stdin>", line 5, in inside
UnboundLocalError: local variable 'x' referenced before assignment
Selon les règles, la inside
函数里,为什么x不指向原来的'outside'
chaîne a-t-elle été saisie à ce moment-là ?
Les variables non définies ne devraient-elles pas produire NameError
Pourquoi pas ici ?
Au départ, je pensais que les chaînes et les listes étaient similaires aux pointeurs en C, mais il semble que ce ne soit pas le cas maintenant. Si possible, j'espère donner une introduction à ce point, merci.
我想大声告诉你2017-05-18 10:55:10
Répondez un par un de facile à difficile, car c'est mon humble opinion, donc si quelqu'un voit que c'est incorrect, j'espère que vous pourrez le signaler
Similaire aux pointeurs en C#🎜 🎜# : C'est correct, car dans py
, presque tout est un objet Même lors de l'attribution de valeurs aux variables, les objets
sont générés en premier, puis le . les variables
sont créées. code> pointe vers cet objet
, et les objets sont également divisés en objets mutables
et objets immuables
. avec objets mutables
>Lors du fonctionnement, cela affectera d'autres variables pointant vers cet objet, par exemple :
o = [1, 2, 3, 4]
b = o
print id(o)
print id(b)
b[1] = 123123
print b
print o
输出:
39946376
39946376
[1, 123123, 3, 4]
[1, 123123, 3, 4] # o指向的列表也被改变
py
里面, 几乎所有的事物都是对象, 就连变量赋值, 也是先生成对象
, 再让变量
指向这个对象
,而对象还分可变对象
和不可变对象
, 在对可变对象
操作时, 是会影响到其他指向这个对象的变量, 例如:
s = '123123'
print id(s)
s = '32131'
print id(s)
# 输出:
41392768
41392808
而对于不可变对象
, 是直接就放弃旧的对象, 而指向新的对象, 例如:
x='outside'
print(id(x))
def inside():
print(id(x))
x='inside'
print(id(x))
所以你在操作python对象时, 需要谨记该对象是属于哪种类型, 你的操作又会不会因为这些特性而失败或者没达到自己想要的效果.
未定义的变量: python在查找变量时, 将遵循LEGB的顺序, 只有都查找完毕还是没找到的情况下, 才会触发NameError
异常, 这个可以参考我的一篇博文: Python: 作用域(scope) 和 LEGB
UnboundLocalError: 这个问题是最常见, 也是最难解释的, 因为我们总是相当然地觉得, 它必定就会根据ELGB的顺序去查到变量;其实我们的理解并没错误, 只是我们忽略了一点:赋值语句
Pour les objets immuables
, l'ancien objet est directement abandonné et pointe vers le nouvel objet, par exemple :
NameError
Exception, vous pouvez vous référer à un de mes articles de blog pour cela : Python : Scope et LEGB#🎜🎜#
#🎜🎜##🎜🎜#UnboundLocalError#🎜🎜# : Ce problème est le plus courant et le plus difficile à expliquer, car nous tenons toujours pour acquis qu'il trouvera les variables selon l'ordre d'ELGB en fait, nous Il n'y a rien de mal dans notre compréhension, mais nous avons oublié un point : Instruction d'affectation
S'il n'y a pas d'instruction d'affectation dans le segment de code de fonction, alors ce problème ne se produira pas, mais pourquoi une erreur. se produit-il lorsqu'une instruction d'affectation apparaît ? C'est la même chose que Cela est lié à la portée de python. Comme mentionné dans l'article ci-dessus, la portée de python n'est pas dynamique, mais statique. Cela peut être vu à partir de l'indentation du fichier de script. , donc dans le code : #🎜🎜#rrreee
Ininside
中, 已经有了赋值语句, 所以对于x
,他已经不会从enclosing
或者global
甚至bulitin
里面去查找, 它已经被认定在local
域了, 只是这个值并没有和真正的对象'inside'
建立起绑定关系, 因为代码没有运行到真正的赋值语句, 所以, 会触发这个UnboundLocalError
. 而为什么那个列表会可以那样做, 因为他们两个是完全不同的操作, 同样都是print(id(x))list的操作字节码是LOAD_DEREF
, 而字符串的操作字节码是LOAD_FAST
, 而x[:]=[1,2,3]/x='inside'分别对应的字节码又是STORE_SLICE+3
和 STORE_FAST
, 前者是在原来的基础上修改, 而后者是重新指向新的对象, 而这两种方式的区别, 决定了,它们在构建函数时, 以怎样的形式存放x
, 这个就涉及到python函数
构建的原理了, 有兴趣可以看看源码中的object/ceval.c源码
, 这是虚拟机运行的原理, 关于这个问题可以简单看我另一篇文章, 比较简单将UnboundLocalError
: Parlons de la magique UnboundLocalError : variable locale x référencée avant l'affectation
某草草2017-05-18 10:55:10
Vous avez réaffecté une nouvelle variable x dans la fonction interne, et les portées des deux x sont différentes.
L'UnboundLocalError est due au fait que vous avez imprimé une variable non initialisée dans la portée interne.
Regardez cette explication pour plus de détails :
https://docs.python.org/2/faq...
PHP中文网2017-05-18 10:55:10
En gros, Lin_R l'a dit très clairement.
Les domaines des fonctions externes et des fonctions internes sont différents. Puisque vous avez attribué une valeur à x dans la fonction inside, lorsque la variable x est utilisée dans la fonction inside, x est considéré comme étant dans le domaine local de inside. Pour le moment, x n'utilisera pas les valeurs des autres champs. Ainsi, lors de l'impression de (x), comme x n'a pas de valeur initialisée, une erreur se produit. Bien qu’il soit possible d’utiliser des variables définies mais non attribuées en C, Python ne le permet pas.
En python3, il existe une instruction non locale qui peut résoudre ce problème.
def outside():
x='outside'
print(id(x))
def inside():
nonlocal x
print(id(x))
x='inside'
print(id(x))
inside()
print(id(x))
print(x)
Notez qu'il n'est pas possible d'utiliser l'instruction global
pour le moment car il n'y a pas de variable x dans le domaine global.