简体   繁体   English

从Lambda内部访问全局

[英]Accessing global from within lambda

I never access globals from within functions, instead I pass them in as arguments. 我从不从函数内部访问全局变量,而是将它们作为参数传递。 Therefore the following code feels weird to me, where I am accessing a global object directly from within the function: 因此,下面的代码让我感到很奇怪,在这里我直接从函数内部访问全局对象:

ws = WebSocket(url)
sch.on_receive(lambda msg: ws.send(msg))

How should I be doing this? 我应该怎么做?

There is no problem with accessing global variables from functions (including lambdas), without using global : 在不使用global情况下,从函数(包括lambda) 访问全局变量没有问题。

>>> a = 1
>>> b = list()
>>>
>>> def f():
...     b.append(a)
...
>>> f()
>>> print(b)
[1]

As you can see above, a global variable can be read and the object in the variable can be used without any restrictions. 从上面可以看到,可以读取全局变量,并且可以无限制地使用变量中的对象。

What can not be done without a global is assigning an object to a global variable. 不能没有做什么global分配一个对象到一个全局变量。 That is because an assignment automatically creates a local variable. 那是因为赋值会自动创建一个局部变量。

def f():
    a = 4  # this is a new local variable a, regardless of whether there is a global 'a'

Hence, the following is fine: 因此,以下情况很好:

ws = WebSocket(url)
sch.on_receive(lambda msg: ws.send(msg))

On the other hand, if you really wanted to assign value to a global variable, that would be impossible within a lambda (other than by hacks, such as accessing the globals directory...) 另一方面,如果您真的想为全局变量赋值,那么在lambda中是不可能的(除了被黑客入侵之外,例如访问globals目录...)

What's wrong with what you've written? 你写的东西怎么了? It's not necessarily accessing the global scope, it's really accessing the local scope (and if it doesn't find the variable uses the global scope). 它并不一定要访问全局范围,它实际上是在访问局部范围(如果找不到变量使用全局范围)。 Just as an example this is perfectly fine: 举个例子,这很好:

def func():
    ws = WebSocket(url)
    sch.on_receive(lambda msg: ws.send(msg))

Because of this I think of it more as a closure than accessing globals. 因此,我将其更多地看作是封闭而不是访问全局变量。 If you didn't do this with a lambda here's how you could do it: 如果您不使用lambda此操作,请按以下步骤操作:

def wrapper(url):
    ws = WebSocket(url)
    def send(msg):
        return ws.send(msg)
    return send

sch.on_receive(wrapper(url))

Or more tersely: 或更简洁:

wrapper = lambda url: Websocket(url).send
sch.on_receive(wrapper(url))

But this is really just the equivalent of: 但这实际上只相当于:

sch.on_recieve(WebSocket(url).send)

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

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