开发者

pythonic approach to dynamic class variable names (ala PHP's $$var)

开发者 https://www.devze.com 2022-12-09 06:02 出处:网络
The following code: class Log: BAT_STATS = [\'AB\', \'R\', \'H\', \'HR\'] def __init__(self, type): for cat in Log.BAT_STATS:

The following code:

class Log:

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

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

I want the loop there to create a class property of each key in BAT_STATS, so I can go:

log =开发者_如何学Go Log()
print log.HR;

Similar to PHP with $this->$$foo = 'bar' where $foo would be 'HR'.


Maybe this?

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

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

EDIT - Oops, indentation was a bit messed up.

@EOL: Are you suggesting putting it straight into the class definition? While for some applications it might be nice just to set these values once for the class rather than per-instance, I'm not sure how you'd do that. Inside the class definition you don't have a "self" or "klass" variable to call setattr on. At the end of the class definition Python parcels up the locals dictionary to use as the class's member dictionary. You can read this dictionary directly with locals(), but I don't think you have any guarantee that you can write back to it. I would guess that the easiest way to get the effect is to modify the class dictionary after it has been created, but that could be quite confusing because then the class's behaviour is no longer clear just from looking at its definition. It's not necessarily a bad idea, but I wouldn't like to recommend it without having a better understanding of the scenario it's going to be used in.


Explicit recommendation: DO NOT USE the following.
and please ease-up on the downvotes...

Edit: I even found a quote from Alex Martelli expressing how bad an idea my snippet is.
(Short excerpt from Python in a Nutshell, 2nd ed. O'Reilly 2006)
Use exec only when it is really indispensable. MOst often, it's best to avoid exec choose more specific, well-well controlled mechanisms instead: exec pries loose your control on your code's namespace, damages performance and exposes you to numerours, hard-to-find bugs.

Therefore here is my not so pythonic moment:

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

Using setattr() is of course cleaner (I recommend it in this simple case), but it's nice to remember the power of exec... A bit like being reminded of a dangerous tool we have in the shed.

0

精彩评论

暂无评论...
验证码 换一张
取 消