【问题标题】:Python create function that automatically creates variable within function that calls it?Python创建函数在调用它的函数中自动创建变量?
【发布时间】:2021-09-23 05:05:42
【问题描述】:

假设我有这个带有很多变量设置的函数:

def set_variables():
    var_a = 10
    var_b = 200

这些变量需要在多个函数中设置并通过它们的变量名访问。有没有办法创建这个函数 s.t.在调用它的父函数之后,调用它有var_avar_b 而不必返回它们?上面的函数是一个例子,但实际上有很多变量,所以像下面这样的函数并不可行。

def parent_function():
   var_a, var_b, ... = set_variables()

理想情况下,我想要类似的东西

def parent_function():
   set_variables()
   # do some code with var_a or var_b

或者甚至可能返回keyval 的字典并自动生成名称为key 的变量设置为val

例如

def parent_function():
    var_dict = set_variables()
    some_func_to_auto_set_vars_from_dict(var_dict)
    # Do something with var_a or var_b

【问题讨论】:

  • 你可以在一个函数中创建全局变量,但你不能在一个单独的函数中为一个函数创建局部变量,如果你想这样做的话。
  • 您正在寻找动态范围的变量:Python 是 lexically 范围的。你想要的都是不可能的。
  • 如果您愿意让set_variables 返回一个值,只需返回一个dict 而不是多个值。
  • 这似乎是开始学习面向对象编程的好时机。
  • 如果您反对 OOP,至少有什么特别的原因表明您不只是在函数定义中使用参数吗?如果set_variables() 要简单地返回任何必要的变量,那么您可以将这些变量传递给parent_function()

标签: python


【解决方案1】:

返回一个集合,使您可以按名称访问值而无需重新分配它们,例如一个字典:

def set_variables():
    return {
        'a': 10,
        'b': 200,
    }
def parent_function():
   v = set_variables()
   # do some code with v['a'] or v['b']

或者(我个人对此用例的偏好)NamedTuple,它为您提供类型检查(和 IDE 自动完成,就像您使用顶级命名变量一样)的好处:

from typing import NamedTuple

class Vars(NamedTuple):
    a: int
    b: int

def set_variables() -> Vars:
    return Vars(a=10, b=200)

def parent_function():
    v = set_variables()
    # do some code with v.a and v.b

【讨论】:

  • 有没有办法在parent_function 中将字典转换为以key 命名的变量,其值为val
  • 使用NamedTuple IMO - 扩展答案以显示其工作原理。
  • 请注意,vars 是您正在跟踪的内置函数。
【解决方案2】:

让所有函数设置所有变量似乎很容易。但这种隐含的状态共享已被证明是维护的噩梦。

相反,使用不可变的数据类;它们或多或少地提供了您所要求的便利,但可以更轻松地对代码进行推理。

@dataclass
class Settings:
  a: str =""
  b: int =5
  ...

def parent():
  s = initialize(Settings(c=[1,2,3]))
  use(s.a, s.b)
  ...

def initialize (s: Settings):
  return dataclass.replace(s,
      b=10, d="@#$_"
    )

【讨论】:

    猜你喜欢
    • 2016-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-13
    • 1970-01-01
    • 1970-01-01
    • 2010-09-12
    • 2019-08-25
    相关资源
    最近更新 更多