2

I have two questions:

1) I want to write a statement like: superVar = [subVar1 = 'a', subVar2 = 'b']

After this statement, I want:

superVar = ['a', 'b']

subVar1 = 'a'

subVar2 = 'b'

Is this somehow achievable in python?

2) I want to do the following inside a class's init function:

self.superVar = [v1 = 'a', v2 = 'b']

After this statement, I want:

self.superVar = ['a', 'b']

self.superVar.v1 = 'a'

self.superVar.v2 = 'b'

i.e. have 'superVar' be part of the name of the other variables.

As you might have guessed, what I really want to do is (2) above. (1) is just the first step and I would be happy even with that, if (2) is not possible.

Thanks a lot! Gaurav

user10
  • 2,126
  • 5
  • 19
  • 26
  • #1 is not possible. #2 is not exactly possible, but an approximation is potentially possible with an ugly hack. Why do you feel the need to do this instead of just assigning the variables separately, in order? – BrenBarn Jun 25 '13 at 02:39
  • The sub-variables collectively form a logical unit. e.g. suppose the superVar represents a phone book entry, and the sub-variables are first name, last name, etc. So I want to keep the sub-variables corresponding to the same logical unit together. I want the sub-variable names to contain the super-variable name since these variables might be modified individually outside the class. So someone could assign superVar.v1 = 'c' from outside. I could write the full long names, but that will make it look a little ugly / clunky. – user10 Jun 25 '13 at 02:44
  • 1
    you can do 1) with `superVar = ['a','b']; subVar1, subVar2 = superVar;` – SheetJS Jun 25 '13 at 02:45
  • Thanks Nirk. I was thinking about that too, but ditched it, since I really wanted to do (2). – user10 Jun 25 '13 at 02:57

5 Answers5

3
>>> from collections import namedtuple
>>> T = namedtuple('supervar', ['v1', 'v2'])
>>> superVar = T('a', 'b')
>>> superVar.v1
'a'
>>> superVar.v2
'b'
John La Rooy
  • 295,403
  • 53
  • 369
  • 502
2

Do you mean a dictionary?

superVar = {'subVar1': 'a', 'subVar2': 'b'}
superVar['subVar1']
# 'a'
superVar['subVar2']
# 'b'

In a class:

class Foo(object):
    def __init__(self, a, b):
        self.superVar = {'subVar1' : a, 'subVar2' : b}


bar = Foo('one', 'two')
bar.superVar.values()
# ['one', 'two']

If you want to keep order, you can use an ordered dictionary from the collections module.

TerryA
  • 58,805
  • 11
  • 114
  • 143
  • No. I do care about the order of the variables in superVar. The basic thing I am trying to achieve is to make the code compact and easy to read. (BTW, I did not down vote your answer). – user10 Jun 25 '13 at 02:48
  • 1
    @TheNoob If you care about order, you can always use an [ordered dictionary](http://docs.python.org/2/library/collections.html#collections.OrderedDict) – TerryA Jun 25 '13 at 02:50
  • I ended up using an OrderedDict. It solves my problem nicely. Can you please edit your answer to an OrderedDict (or at least mention it in the answer) so that I can mark this as the accepted answer? – user10 Jun 25 '13 at 05:16
  • @TheNoob Added :). I would add an example, but I truly have never worked with one, just seen it before. Sorry – TerryA Jun 25 '13 at 05:19
2

In Python, assignments are statements, not expressions. You can't chain together statements. So (1) is impossible.
However, you can use keyword arguments in the __init__ method of a class to get the behavior in (2):

>>> class Test:
        def __init__(self, **kwargs):
            print "the keyword arguments are", kwargs #kwargs is a dictionary
            for x in kwargs:
                setattr(self, x, kwargs[x]) #adds an attribute from kwargs to self

>>> t = Test(var1=1234,var2='hello',var3=45.234)
the keyword arguments are {'var1': 1234, 'var3': 45.234, 'var2': 'hello'}
>>> t.var1
1234
>>> t.var2
'hello'
>>> t.var3
45.234
>>> 
Community
  • 1
  • 1
  • I know about keyword arguments. However, I have a large number of variables. So my plan is to have all the variables defined in the init, and then the user of the class can just override the variables he/she wants. Hence, I can't go down this path. – user10 Jun 25 '13 at 02:59
2

Why not create a dictionary for your subVars and make superVar a list of values from the subVar dictionary?

d = {'subVar1': 'value1', 'subVar2': 'value2'}
superVar = d.values()
Lbatson
  • 1,017
  • 8
  • 18
1

This is basically the same as Jeremy Bentham's answer,

class T:

    def __init__(self):
        self.SuperVar = {'v1':'a', 'v2':'b'}
        print self.SuperVar.v1
        print self.SuperVar.v2

    def __setattr__(self, k, v):

        class SuperVar:
            def __setattr__(self, k, v):
                self.__dict__[k] = v

        if k == "SuperVar":
            self.__dict__["SuperVar"] = SuperVar()
            for k in v:
                self.__dict__["SuperVar"].__setattr__(k, v[k])
        else:
            self.__dict__[k] = v


t = T()
John
  • 13,197
  • 7
  • 51
  • 101