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.
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, lesobjets
sont générés en premier, puis le. les variables
sont créées. code> pointe vers cetobjet
, et les objets sont également divisés enobjets mutables
etobjets immuables
. avecobjets mutables
>Lors du fonctionnement, cela affectera d'autres variables pointant vers cet objet, par exemple :py
里面, 几乎所有的事物都是对象, 就连变量赋值, 也是先生成对象
, 再让变量
指向这个对象
,而对象还分可变对象
和不可变对象
, 在对可变对象
操作时, 是会影响到其他指向这个对象的变量, 例如:而对于
不可变对象
, 是直接就放弃旧的对象, 而指向新的对象, 例如:所以你在操作python对象时, 需要谨记该对象是属于哪种类型, 你的操作又会不会因为这些特性而失败或者没达到自己想要的效果.
未定义的变量: python在查找变量时, 将遵循LEGB的顺序, 只有都查找完毕还是没找到的情况下, 才会触发
NameError
异常, 这个可以参考我的一篇博文: Python: 作用域(scope) 和 LEGBUnboundLocalError: 这个问题是最常见, 也是最难解释的, 因为我们总是相当然地觉得, 它必定就会根据ELGB的顺序去查到变量;其实我们的理解并没错误, 只是我们忽略了一点:
rrreee #🎜🎜#Ainsi, lorsque vous utilisez un objet Python, vous devez garder à l'esprit à quel type appartient l'objet et si votre opération échouera ou n'obtiendra pas l'effet souhaité en raison de ces caractéristiques.#🎜🎜# #🎜🎜##🎜🎜#Variables non définies#🎜🎜# : Lorsque python recherche des variables, il suivra l'ordre de LEGB. Ce n'est que lorsque toutes les recherches seront terminées ou introuvables que赋值语句
Pour lesobjets immuables
, l'ancien objet est directement abandonné et pointe vers le nouvel objet, par exemple :NameError
sera déclenché. >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 : #🎜🎜#rrreeeIn
inside
中, 已经有了赋值语句, 所以对于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'affectationVous 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...
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.
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.