How do I access/modify variables from a function&#

2019-07-22 13:02发布

问题:

If I have a function which has some non-local variable (in a closure), how do I access that variable? Can I modify it, and if so, how? Here's an example of such a function:

def outer():
    x = 1
    def inner(y):
        nonlocal x
        return x + y
    return inner

inner = outer()
# how do I get / change the value of x inside inner?

(apologies if this is already answered elsewhere; I couldn't find it, so I thought I would share the answer once I worked it out)

回答1:

A function's enclosed variables are stored as a tuple in the __closure__ attribute. The variables are stored as a cell type, which seems to just be a mutable container for the variable itself. You can access the variable a cell stores as cell.cell_contents. Because cells are mutable, you can change the values of a function's non-local variables by changing the cell contents. Here's an example:

def outer():
    x = 1
    def inner(y):
        nonlocal x
        return x + y
    return inner

inner = outer()

print(inner(2))  # 3
print(inner.__closure__)  # (<cell at 0x7f14356caf78: int object at 0x56487ab30380>,)
print(inner.__closure__[0].cell_contents)  # 1

inner.__closure__[0].cell_contents = 10
print(inner(2))  # 12
print(inner.__closure__[0].cell_contents)  # 10

EDIT - the above answer applies to Python 3.7+. For other Python versions, you can access the closure the same way, but you can't modify the enclosed variables (here's the Python issue that tracked setting cell values).