简体   繁体   English

python 中的 scope 不一致

[英]Inconsistent scope in python

I have tried creating a function like this:我试过像这样创建一个 function :

n = ["one", "two"]
result=""
def join_strings(words):
  for word in words:
    result+=word
  return result
print (join_strings(n))

This does not work and outputs:这不起作用并输出:

UnboundLocalError: local variable 'result' referenced before assignment

The result variable has to be inside the function for it to work.结果变量必须在function 内才能工作。

However, when I have this simple function:但是,当我有这个简单的 function 时:

x=3
def price():
  return (x+3)
print (price())

This works and prints the price, even though x is outside of the function.即使 x 在 function之外,这也可以工作并打印价格。 Why is this happening?为什么会这样?

Actually there is no inconsistency as the examples you gave are different from each other.实际上没有不一致,因为您提供的示例彼此不同。 It would still fail in the second function if you have tried to assign x to itself, like:如果您尝试将x分配给自身,它仍然会在第二个 function 中失败,例如:

>>> x = 3
>>> def price():
...     x +=3
...     return x
...
>>> price()
UnboundLocalError: local variable 'x' referenced before assignment

Instead of assigning back to x if you choose another name, it would run with no problem:如果您选择另一个名称,而不是分配回x ,它将毫无问题地运行:

>>> def price():
...     y  = x + 3
...     return y
...
>>> price()
6

But, why it happens?但是,为什么会发生呢?

It's because Python's scoping rules.这是因为 Python 的作用域规则。 You can read the value of a variable outside of function but you can't change it**.您可以读取 function 之外的变量值,但不能更改它**。 When you do x += 3 , which is same as x = x + 3 for integers, that means " I have a variable x that I have write access to it in the current scope. " You don't have such variable, thus as the error says: you are referencing a "local variable" before assignment.当您执行x += 3时,这与整数的x = x + 3相同,这意味着“我有一个变量x我可以在当前 scope 中对其进行写访问。 ”您没有这样的变量,因此正如错误所说:您在分配之前引用了“局部变量”。

Is there a way to modify them in the function?有没有办法在 function 中修改它们?

Yes.是的。 You can use global keyword, changes will be applied to your global variable:您可以使用global关键字,更改将应用于您的全局变量:

>>> x = 3
>>> def price():
...     global x
...     x += 3
...     return x
...
>>> x
3
>>> price()
6
>>> x
6

** By changing , I mean assigning something else to it so it's id will change. ** 通过改变,我的意思是给它分配别的东西,所以它的id会改变。

The difference is that in the second example you aren't trying to modify or reassign x .不同之处在于,在第二个示例中,您没有尝试修改或重新分配x (You'll get the same error if you say something like x += 3 in the price function.) Once you use an assignment operator, you're binding a new value to that name, shadowing the outer scope. (如果您在price function 中说x += 3之类的内容,您将得到相同的错误。)一旦您使用赋值运算符,您将一个新值绑定到该名称,从而隐藏外部 scope。

If you want to be able to modify something from an outer scope, put it inside a mutable container (like a list);如果您希望能够从外部 scope 修改某些内容,请将其放入可变容器(如列表)中; you can then modify the contents without reassigning that variable.然后,您可以修改内容而无需重新分配该变量。

result = [""]
def join_strings(words):
    for word in words:
        result[0] += word
    return result[0]

If you just want to be able to reference the result value, without modifying it, that's fine too, but you have to assign it to a new variable then:如果您只想能够引用result值而不修改它,那也可以,但是您必须将其分配给一个新变量:

result = ""
def join_strings(words):
    ret = result
    for word in words:
        ret += word
    return ret

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM