【问题标题】:Concatenate string literals to generate variable name连接字符串文字以生成变量名
【发布时间】:2017-12-22 19:45:39
【问题描述】:

问题

python 中,创建允许我通过连接两个字符串文字来访问变量以生成变量名称的函数的最短/最简单方法是什么?


背景

C,我可以这样做:

#define CONCAT(x,y) x ## _ ## y

然后,稍后在我的代码中,我可以执行以下操作:

int i = CONCAT(PRODUCT,BANANA).

假设存在名为 PRODUCT_BANANA 的宏,现在将其值分配给 i。我可以通过间接在 shell 脚本中完成类似的事情。


问题 - Redux

如何在python 中实现相同的功能?我这样做是因为我有一个 python 类,其中包含数十种不同产品的数千个变量,即

class A(object):
    BANANA_ADDRESS0 = 0xABCD;
    PINEAPPLE_ADDRESS0 = 0x1234;
    BANANA_ADDRESS1 = 0x4567;
    PINEAPPLE_ADDRESS1 = 0x1000;

我希望能够有一个函数,例如,可以通过someFunc("BANANA", "ADDRESS0") 执行,将值解析为A.BANANA_ADDRESS0,并返回相关值(在本例中为0xABCD)。


额外

假设上述是可能的,是否可以让函数始终将提供的函数参数解释为字符串文字,因此函数调用不需要用单引号/双引号括起来的参数?也就是说,它可以通过someFunc(BANANA, ADDRESS0)而不是someFunc("BANANA", "ADDRESS0")调用?

【问题讨论】:

  • 常见的是先构建一个字符串,然后使用getattr内置:getattr(A_obj, var_name)
  • 你为什么不用字典呢? A={"BANANA_ADDRESS0:0xABCD}` 并使用 A["BANANA"+"_"+"ADDRESS0"] 访问它(并且可能用变量替换“BANANA”和“ADDRESS0”?
  • 如果您需要将其设为全局变量,请使用 vars() 函数,该函数允许您设置和获取全局变量
  • @MEE 代码是动态生成的,脚本要求名称是“交错的”(即为所有产品创建ADDRESS0的定义,为所有产品创建ADDRESS1的定义等)。我需要能够在不更改定义的情况下提取值。
  • 如果你想访问(设置/写入)变量 var1 的值,只需这样做:A[var1 + "_" + (some way to get the second part)]

标签: python python-2.7 variables variable-names


【解决方案1】:

第一部分很简单:

class A(object):
    BANANA_ADDRESS0 = 0xABCD;
    PINEAPPLE_ADDRESS0 = 0x1234;
    BANANA_ADDRESS1 = 0x4567;
    PINEAPPLE_ADDRESS1 = 0x1000;

    @classmethod
    def some_func(cls, name_a, name_b):
        name = '{}_{}'.format(name_a, name_b)
        return getattr(cls, name)

value = A.some_func('BANANA', 'ADDRESS1')

但是第二部分是不可能的,除非你有一组有限的名字,在这种情况下你也必须有

BANANA = 'BANANA'
PINEAPPLE = 'PINEAPPLE'

【讨论】:

    【解决方案2】:

    如果您只想对类/实例属性执行此操作,则需要getattr。它接受一个字符串参数,你可以用任何你喜欢的方式构造它:

    getattr(A, "BANANA" + "_" + "ADDRESS0")
    

    如果您愿意,当然可以编写一个简单的包装器,但在我看来,这将是无益的混淆。

    以任何您想要的方式构建传递给getattr 的字符串,包括在适当的情况下使用for 循环等其他构造。例如,假设您有属性名称元素的可迭代对象并且想要全部获取它们:

    for first_part in first_parts:
       for second_part in second_parts:
           print(getattr(A, first_part + "_" + second_part))
    

    对于您的“额外”块 - 好吧,BANANA 表示名为 BANANA 的变量,而不是文字字符串。如果你真的想要,你可以定义这样一个字符串常量,但我不会。没有什么好方法可以告诉 Python 始终假定未解析的变量名实际上是字符串字面量,我认为如果可以的话,这样做是个坏主意。

    【讨论】:

      【解决方案3】:

      只需使用dict。即

      A = {
          "BANANA_ADDRESS0": 0xABCD,
          "PINEAPPLE_ADDRESS0": 0x1234,
          "PINEAPPLE_ADDRESS1": 0x1000
      } 
      

      然后你可以这样做:

      var1 = "BANANA" # or any other value
      var2 = "ADDRESS0" # or any other value
      myValue = A[var1 + "_"  + var2]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-30
        • 2023-03-07
        相关资源
        最近更新 更多