3

This is a followup to function that returns a dict whose keys are the names of the input arguments, which I learned many things (paraphrased):

  • Python objects, on the whole, don't know their names.
  • No, this is not possible in general with *args. You'll have to use keyword arguments
  • When the number of arguments is fixed, you can do this with locals
  • Using globals(). This will only work if the values are unique in the module scope, so it's fragile
  • You're probably better off not doing this anyway and rethinking the problem.

The first point highlighting my fundamental misunderstanding of Python variables. The responses were very pedagogic and nearly instantaneous, clearly this is both a well-understood yet easily confused topic.

Since I'd like to learn how to do things proper, is it considered bad practice to create a dummy class to simply hold the variables with names attached to them?

class system: pass
S = system ()
S.T = 1.0
S.N = 20
S.L = 10

print vars(S)

This accomplishes my original intent, but I'm left wondering if there is something I'm not considering that can bite me later.

Community
  • 1
  • 1
Hooked
  • 84,485
  • 43
  • 192
  • 261
  • 4
    I still don't get what your actual aim is. The Python data structure for "values with names" is a dictionary: `dict(T=1.0, N=20, L=10)`. There are cases where some people prefer namespace objects like the one you used, but without more context, it is hard to give recommendations. – Sven Marnach Mar 06 '12 at 15:40
  • Am I missing something? What does that give you that dictionaries don't? – Paolo Bergantino Mar 06 '12 at 15:41
  • 1
    @PaoloBergantino: As an example, `argparse` uses such namespace objects because sometimes it is more convenient to access attributes via `S.T` than the more noisy `S["T"]`. – Sven Marnach Mar 06 '12 at 15:43

2 Answers2

3

I do it as a homage to Javascript, where you don't have any distinction between dictionaries and instance variables. I think it's not necessarily an antipattern, also because differently from dictionaries, if you don't have the value it raises AttributeError instead of KeyError, and it is easier to spot typos of the name. As I said, not an antipattern, provided that

  1. the scope of the class is restricted to a very specific usage
  2. the routine or method you are calling (e.g. vars in your example) is private in nature. I would not want a public interface with that calling semantics, nor I want it as a returned entity
  3. the name of the "dummy" class is extremely clear in its intent and the kind of aggregate it represents.
  4. the lifetime of that object is short and uneventful. It is just a temporary bag of data.

If these constraints are not respected, go for a fully recognized class with properties.

Stefano Borini
  • 138,652
  • 96
  • 297
  • 431
2

you can do that, but why not use a dictionary?

but if you do that, you're better off passing keywords args to the class's constructor, and then let the constructor copy them to the app's members. something like:

class Foo(object):

    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)
Not_a_Golfer
  • 47,012
  • 14
  • 126
  • 92
  • You can also make do without copying: `self.__dict__ = kwargs`. – Sven Marnach Mar 06 '12 at 15:46
  • Does this require you to know all the input arguments at the time of the construction? What does this gain over adding a member with `S.x`? – Hooked Mar 06 '12 at 15:47
  • @SvenMarnach yeah, but then you can't add any methods to the class like a custom `__repr__` – Not_a_Golfer Mar 06 '12 at 15:48
  • @Hooked it's just less lines of code and less code to write. you can do both if you like. – Not_a_Golfer Mar 06 '12 at 15:49
  • @SvenMarnach you're right, it won't override it, unless you pass an argument called `__repr__` :) my bad – Not_a_Golfer Mar 06 '12 at 15:57
  • it is indeed off topic, but I tried it and passing `__repr__` as an argument to such a class does in fact change the `__repr__` method http://pastebin.com/eKdUsdNU maybe it's just old style classes? don't have time to check ;) – Not_a_Golfer Mar 06 '12 at 16:07
  • @DvirVolk: Yes, for old-style classes this was possible. The last time I used them is about a decade ago, so I forgot about this. Thanks for the heads-up! (Note that the same thing would happen with your implementation -- no difference in this regard.) – Sven Marnach Mar 06 '12 at 16:17