我正在尝试创建一个设置局部变量的脚本,从函数中引用它,并且可以将操纵的值返回给主范围(或者它的任何调用;我是Python的新手)
我已经简化了我的代码,以显示我想要完成的最基本的操作,即我想将模块中的本地导入到功能块中。
我已经通过使用globals
来实现这一点,但这不是最好的解决方案。 。
chambersinreactor = 0;
cardsdiscarded = 0;
def find_chamber_discard():
"""Find chambers and discard in row (reads each player slot)"""
chambersinreactor = 0; # Resets the variable, not what I want
cardsdiscarded = 0; # Resets the variable, not what I want
chambersinreactor += 1
cardsdiscarded += 1
return # Don't know what to put here
find_chamber_discard()
print chambersinreactor # prints as 0, should be 1
print cardsdiscarded # prints as 0, should be 1
答案 0 :(得分:19)
函数不应该知道它们被调用的范围;函数的要点是创建一个可重用的代码块,可以从不同的地方多次调用。
通过将函数传递给输入变量,将信息传递给。该函数通过返回信息将信息传回给调用者。
管理作用域的变量是该作用域的作用不它调用的任何函数。如果需要将变量设置为由函数确定的值,那么您可以使用函数返回这些值,并使用它们来设置变量。如果函数计算的值取决于调用范围中的变量值,则需要将它们作为参数传递给函数。你正在调用的函数不应该知道你正在使用什么变量,并且不应该弄乱它们。
把所有这些放在一起,你想要做的是这样的:
def find_chamber_discard(chambersinreactor, cardsdiscarded):
chambersinreactor += 1
cardsdiscarded += 1
return (chambersinreactor, cardsdiscarded)
chambersinreactor = 0;
cardsdiscarded = 0;
chambersinreactor, cardsdiscarded = find_chamber_discard(chambersinreactor, cardsdiscarded)
print chambersinreactor
print cardsdiscarded
有很多方法可以通过全局变量或操纵可变数据结构来解决这个问题,但最终它们会使您的程序不那么灵活,并且更容易包含难以发现的错误。这些技术有一席之地,但是您与函数进行信息交流的第一种方法实际上应该是传递参数并接收返回值。
答案 1 :(得分:2)
#!/usr/bin/env python
chambersinreactor = 0; cardsdiscarded = 0;
def find_chamber_discard():
chambersinreactor = 0
cardsdiscarded = 0
chambersinreactor += 1
cardsdiscarded += 1
return(chambersinreactor, cardsdiscarded)
#Here the globals remain unchanged by the locals.
#In python, a scope is similar to a 'namespace'
find_chamber_discard()
print chambersinreactor #prints as 0
print cardsdiscarded
#I've modified the function to return a pair (tuple) of numbers.
#Above I ignored them. Now I'm going to assign the variables in the
#main name space to the result of the function call.
print("=====with assignment===")
(chambersinreactor, cardsdiscarded) = find_chamber_discard()
print chambersinreactor # now prints as 1
print cardsdiscarded
# Here is another way that doesn't depend on returning values.
#Pass a dictionary of all the main variables into your function
#and directly access them from within the function as needed
print("=======using locals===")
def find_chamber_discard2(_locals):
_locals['chambersinreactor'] += 1
_locals['cardsdiscarded'] += 1
return
find_chamber_discard2(locals())
print chambersinreactor #incremented the value, which was already 1
print cardsdiscarded
答案 2 :(得分:2)
一种方法是使用可变值,如dicts或列表:
settings = dict(
chambersinreactor = 0,
cardsdiscarded = 0
)
def find_chamber_discard():
settings['chambersinreactor'] += 1
settings['cardsdiscarded'] += 1
find_chamber_discard()
print settings['chambersinreactor']
print settings['cardsdiscarded']
但是,如果你有一个正在改变某种状态的函数,你可能最好不要把它全部包装在课堂上,因为这就是它们的用途:
class CardCounter(object):
def __init__(self):
chambersinreactor = 0
cardsdiscarded = 0
def find_chamber_discard(self, hand):
for card in hand:
if card.is_chamber:
self.chambersinreactor += 1
if card.is_discarded:
self.cardsdiscarded += 1
如果您正在计算的是,您可以使用Counter:
from collections import Counter
def test_for_chamberness(x): return x == 'C'
def test_for_discarded(x): return x == 'D'
def chamber_or_discard(card):
if test_for_chamberness(card):
return 'chambersinreactor'
if test_for_discarded(card):
return 'cardsdiscarded'
hand = ['C','C','D','X','D','E','C']
print Counter(
x for x in (chamber_or_discard(card) for card in hand) if x is not None
)
就个人而言,我会采用类方法,甚至包装计数器,因为它将所有相关功能保持在一起。