Pythonic方式设置动态类变量名(类似PHP的$$var)

1 投票
2 回答
546 浏览
提问于 2025-04-15 15:23

下面的代码:

class Log:

    BAT_STATS = ['AB', 'R', 'H', 'HR']

    def __init__(self, type):
        for cat in Log.BAT_STATS:
               self.cat = 0

我想让这个循环为BAT_STATS中的每个键创建一个类的属性,这样我就可以这样使用:

log = Log()
print log.HR;

就像在PHP中用 $this->$$foo = 'bar',其中 $foo 会是 'HR'。

2 个回答

0

明确的建议: 千万不要使用下面的内容。
而且请不要随便给负面评价...

补充说明: 我甚至找到了一段Alex Martelli的话,说明我的代码片段有多糟糕。
(摘自《Python in a Nutshell》,第二版,O'Reilly 2006)
只有在真的必要时才使用exec。大多数情况下,最好避免使用exec,选择更具体、控制更好的方法:exec会让你失去对代码命名空间的控制,影响性能,并且让你面临许多难以发现的错误。

所以这是我不太符合Python风格的时刻:

class Log:
   BAT_STATS = ['AB', 'R', 'H', 'HR']
   def __init__(self):
      for cat in Log.BAT_STATS:
           exec('self.' + cat + ' = 0')

使用setattr()当然更干净(在这个简单的例子中我推荐使用它),但记住exec的强大也是不错的……有点像提醒我们在工具棚里有一个危险的工具。

8

也许是这个?

class Log:
    BAT_STATS = ['AB', 'R', 'H', 'HR']

    def __init__(self, type):
        for cat in Log.BAT_STATS:
            setattr(self, cat, 0)

编辑 - 哎呀,缩进有点乱。

@EOL:你是说直接把它放在类的定义里吗?对于某些应用来说,确实可以只为类设置这些值,而不是每个实例都设置一次。不过,我不太确定怎么做到这一点。在类的定义里,你没有“self”或者“klass”这样的变量可以用来调用设置属性的函数。在类定义结束时,Python会把局部变量打包成一个字典,用作类的成员字典。你可以用 locals() 直接读取这个字典,但我不认为你能保证可以写回去。我猜最简单的办法是,在类创建后修改这个类字典,但这样可能会让人困惑,因为光看定义就不容易理解这个类的行为。这并不一定是个坏主意,但在不了解具体使用场景的情况下,我不太想推荐这样做。

撰写回答