Python:在函数中使用局部变量,从函数返回变量

时间:2021-07-31 17:29:06

I am trying to create a script that sets a local variable, references it from a function, and can return the manipulated value back to the main scope (or whatever it's called; I'm new to Python)

我正在尝试创建一个脚本来设置一个局部变量,从函数中引用它,并且可以将操纵值返回给主范围(或者它的任何调用;我是Python的新手)

I have simplified my code to show the utmost basics of what I am trying to accomplish, which is to import a local from the module into a function block, I think.

我已经简化了我的代码,以显示我想要完成的最基本的东西,即从模块将一个局部导入一个功能块,我想。

I have gotten this to work by using globals, but that isn't the best solution . . .

我已经通过使用全局变量来实现这一点,但这不是最好的解决方案。 。 。

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

3 个解决方案

#1


17  

Functions shouldn't have to know what scope they're called from; the point of a function is to make a re-usable block of code that can be invoked multiple times from different places.

函数不应该知道它们被调用的范围;函数的要点是创建一个可重用的代码块,可以从不同的地方多次调用。

You communicate information to a function by passing it through its input variables. The function communicates information back to its caller by returning it.

您可以通过传递输入变量将信息传递给函数。该函数通过返回信息将信息传回给调用者。

Managing the variables of a scope is the job of the code in that scope not any functions it invokes. If you need to set variables to values determined by a function, then you have the function return those values and you use them to set the variables. If the values the function is calculating depend on the values of variables you have in the calling scope, then you need to pass them to the function as arguments. The function you're calling shouldn't have to know what variables you're using, and shouldn't be able to mess with them.

管理作用域的变量是该作用域中的代码,而不是它调用的任何函数。如果需要将变量设置为由函数确定的值,则可以使用函数返回这些值,并使用它们来设置变量。如果函数计算的值取决于调用范围中的变量值,则需要将它们作为参数传递给函数。您正在调用的函数不应该知道您正在使用的变量,并且不应该弄乱它们。

Putting that all together, what you want to do is something like this:

把所有这些放在一起,你想要做的是这样的:

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

There are ways to get around this with global variables or manipulating mutable data structures, but ultimately they make your program less flexible and more likely to contain errors that will be difficult to spot. There is a place for those techniques, but the first method you reach for to communicate information to and from functions really should be passing arguments and receiving return values.

有办法通过全局变量或操纵可变数据结构来解决这个问题,但最终它们会使您的程序不那么灵活,并且更容易包含难以发现的错误。这些技术有一个地方,但是你可以通过传递参数和接收返回值来实现与函数之间传递信息的第一种方法。

#2


2  

One approach is to use mutable values, like dicts or lists:

一种方法是使用可变值,如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']

However, if you have a function that is changing some state, you're probably better off wrapping that all up in class, as that's what they're for:

但是,如果你有一个正在改变某个状态的函数,你可能最好将它们全部包装在课堂上,因为这就是它们的用途:

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

If what you're doing is counting, maybe you could use Counter:

如果你正在做的是计数,也许你可以使用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
)

Personally, I'd go for the class approach, perhaps even wrapping Counter, as it keeps all the associated functionality together.

就个人而言,我会选择类方法,甚至包装Counter,因为它将所有相关功能保持在一起。

#3


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 

#1


17  

Functions shouldn't have to know what scope they're called from; the point of a function is to make a re-usable block of code that can be invoked multiple times from different places.

函数不应该知道它们被调用的范围;函数的要点是创建一个可重用的代码块,可以从不同的地方多次调用。

You communicate information to a function by passing it through its input variables. The function communicates information back to its caller by returning it.

您可以通过传递输入变量将信息传递给函数。该函数通过返回信息将信息传回给调用者。

Managing the variables of a scope is the job of the code in that scope not any functions it invokes. If you need to set variables to values determined by a function, then you have the function return those values and you use them to set the variables. If the values the function is calculating depend on the values of variables you have in the calling scope, then you need to pass them to the function as arguments. The function you're calling shouldn't have to know what variables you're using, and shouldn't be able to mess with them.

管理作用域的变量是该作用域中的代码,而不是它调用的任何函数。如果需要将变量设置为由函数确定的值,则可以使用函数返回这些值,并使用它们来设置变量。如果函数计算的值取决于调用范围中的变量值,则需要将它们作为参数传递给函数。您正在调用的函数不应该知道您正在使用的变量,并且不应该弄乱它们。

Putting that all together, what you want to do is something like this:

把所有这些放在一起,你想要做的是这样的:

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

There are ways to get around this with global variables or manipulating mutable data structures, but ultimately they make your program less flexible and more likely to contain errors that will be difficult to spot. There is a place for those techniques, but the first method you reach for to communicate information to and from functions really should be passing arguments and receiving return values.

有办法通过全局变量或操纵可变数据结构来解决这个问题,但最终它们会使您的程序不那么灵活,并且更容易包含难以发现的错误。这些技术有一个地方,但是你可以通过传递参数和接收返回值来实现与函数之间传递信息的第一种方法。

#2


2  

One approach is to use mutable values, like dicts or lists:

一种方法是使用可变值,如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']

However, if you have a function that is changing some state, you're probably better off wrapping that all up in class, as that's what they're for:

但是,如果你有一个正在改变某个状态的函数,你可能最好将它们全部包装在课堂上,因为这就是它们的用途:

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

If what you're doing is counting, maybe you could use Counter:

如果你正在做的是计数,也许你可以使用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
)

Personally, I'd go for the class approach, perhaps even wrapping Counter, as it keeps all the associated functionality together.

就个人而言,我会选择类方法,甚至包装Counter,因为它将所有相关功能保持在一起。

#3


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