简体   繁体   English

如何使两个函数共享相同的非全局变量(Python)

[英]How to make two functions share the same non global variable (Python)

Is there a way to make function B to be able to access a non global variable that was declared in only in function A, without return statements from function A. 有没有一种方法可以使函数B能够访问仅在函数A中声明的非全局变量,而无需函数A的返回语句。

As asked, the question: 按照要求,问题是:

Define two functions: 定义两个功能:

  • p : prints the value of a variable p :输出变量的值
  • q : increments the variable q :增加变量

    such that 这样

  • Initial value of the variable is 0. You can't define the variable in the global enviroment. 变量的初始值为0。您无法在全局环境中定义变量。
  • Variable is not located in the global environment and the only way to change it is by invoking q() . 变量不在全局环境中,唯一的更改方法是调用q()
  • The global enviroment should know only p() and q() . 全球环境应该只知道p()q()

    Tip: 1) In python, a function can return more than 1 value. 提示:1)在python中,一个函数可以返回多个值。 2) A function can be assigned to a variable. 2)可以将功能分配给变量。

# Example:
>>> p()
0
>>> q()
>>> q()
>>> p()
2

Using the tips provided as clues, it could be done something like this: 使用提供的提示作为线索,可以完成以下操作:

def make_p_and_q():
    context = {'local_var': 0}

    def p():
        print('{}'.format(context['local_var']))

    def q():
        context['local_var'] += 1

    return p, q

p, q = make_p_and_q()

p()  # --> 0
q()
q()
p()  # --> 2

The question says the global enviroment should know only p and q . 问题是全球环境应该只知道pq

So, taking that literally, it could be done inline using a single function scope: 因此,从字面上看,可以使用单个函数范围内联完成:

>>> p, q = (lambda x=[0]: (lambda: print(x[0]), lambda: x.__setitem__(0, x[0] + 1)))()
>>> p()
0
>>> q()
>>> q()
>>> p()
2

The collection of things that functions can access is generally called its scope . 函数可以访问的事物的集合通常称为其范围 One interpretation of your question is whether B can access a "local variable" of A ; 你的问题的一种解释是,是否B可以访问的“局部变量” A ; that is, one that is defined normally as 即通常定义为

def A():
    x = 1

The answer here is "not easily": Python lets you do a lot, but local variables are one of the things that are not meant to be accessed inside a function. 答案是“不容易”:Python可以做很多事情,但是局部变量是不希望在函数内部访问的事物之一。

I suspect what your teacher is getting at is that A can modify things outside of its scope, in order to send information out without sending it through the return value. 我怀疑您的老师的意思是, A可以修改其范围之外的内容,以便发送信息而无需通过返回值发送信息。 (Whether this is good coding practise is another matter.) For example, functions are themselves Python objects, and you can assign arbitrary properties to Python objects, so you can actually store values on the function object and read them from outside it. (这是否是一种良好的编码习惯,这是另一回事。)例如,函数本身就是Python对象,您可以为Python对象分配任意属性,因此您实际上可以将值存储在函数对象上并从其外部读取它们。

def a():
    a.key = "value"
a()
print a.key

Introspection and hacking with function objects 功能对象的自省和黑客攻击

In fact, you can sort of get at the constant values defined in A by looking at the compiled Python object generated when you define a function. 实际上,您可以通过查看在定义函数时生成的已编译Python对象,来获得A定义的常量值。 For example, in the example above, "value" is a constant, and constants are stored on the code object: 例如,在上面的示例中, "value"是一个常量,并且常量存储在代码对象上:

In [9]: a.func_code.co_consts
Out[9]: (None, 'value')

This is probably not what you meant. 这可能不是您的意思。

Firstly, it's bad practise to do so. 首先,这样做是错误的做法。 Such variables make debugging difficult and are easy to lose track of, especially in complex code. 这样的变量使调试变得困难,并且容易丢失,特别是在复杂的代码中。

Having said that, you can accomplish what you want by declaring a variable as global: 话虽如此,您可以通过将变量声明为全局变量来完成所需的操作:

def funcA():
   global foo
   foo = 3

def funcB():
   print foo # output is 3

That's one weird homework assignment; 那是一项怪异的作业。 especially the tips make me suspect that you've misunderstood or left out something. 特别是提示使我怀疑您误解了或遗漏了一些东西。

Anyway, here's a simpler solution than the accepted answer: Since calls to q increment the value of the variable, it must be a persistent ("static") variable of some sort. 无论如何,这是比接受的答案更简单的解决方案:由于对q调用会增加变量的值,因此它必须是某种持久性(“静态”)变量。 Store it somewhere other than the global namespace, and tell p about it. 将其存储在全局名称空间之外的其他位置 ,并告诉p The obvious place to store it is as an attribute of q : 存储它的明显位置是q的属性:

def q():
    q.x += 1

q.x = 0  # Initialize

def p():
    print(q.x)

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

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