2

I have a Python class, which contains several nested parameter groups:

class MyClass(object):
    #some code to set parameters

    def some_function(self):
        print self.big_parameter_group.small_parameter_group.param_1
        print self.big_parameter_group.small_parameter_group.param_2
        print self.big_parameter_group.small_parameter_group.param_3

I want to reduce code needed to access parameters. What should I place at the top of some_function to access the parameters simply by their names (param_1, param_2, param_3)? And what should I place somewhere in MyClass to apply this shortcut for all its methods, not only some_function?

3 Answers 3

6

I would start the function with

spg = self.big_parameter_group.small_parameter_group

and then use that abbreviation. You could define abbreviations like this in __init__(), I suppose, if you wanted to use them everywhere with self on the front.

Sign up to request clarification or add additional context in comments.

3 Comments

+1, but note that, if you put this in __init__, then the size of the object will increase (also when it's pickled).
Yes, that's what I tried at my code. That helps (and usually is enough), but I'm still curious if I can eliminate even abbreviations.
@user see the 2nd part of my answer. It's a little heavy-handed so you'll probably want to document it, but it should work.
2

One way is to create properties for each of them:

@property
def param_1(self):
    return self.big_parameter_group.small_parameter_group.param_1
@property
def param_2(self):
    return self.big_parameter_group.small_parameter_group.param_2
@property
def param_2(self):
    return self.big_parameter_group.small_parameter_group.param_2

Another more robust but less explicit way would be to override the getattr method like so:

def __getattr__(self, name):
    import re
    p = re.compile('param_[0-9]+')
    if p.match(name):
        return getattr(self.big_parameter_group.small_parameter_group, name)
    else:
        return super(MyClass, self).__getattr__(name)

This will work for any property that matches the format specified by the regex (param_[some number])

Both of these methods will allow you to call self.param_1 etc, but it's just for retriving. If you want to set the attributes you'll need to also create a setter:

@param_1.setter
    def param_1(self, value): 
        print 'called setter'
        self.big_parameter_group.small_parameter_group.param_1 = value

Or to complement getattr:

def __setattr__(self, name, value):
    import re
    p = re.compile('param_[0-9]+')
    if p.match(name):
        return setattr(self.big_parameter_group.small_parameter_group, name, value)
    else:
        return super(MyClass, self).__setattr__(name, value)

(Haven't tested these out so there may be typos but the concept should work)

3 Comments

Namespaces are more than just modules -- dicts, classes, and functions/methods are all also namespaces.
@Ethan It appears you are correct for Python. I was assuming that namespace was the same as for other languages. I don't know if you were the one that downvoted, but if so that seems like a minor reason to downvote.
Bad information is the best reason to downvote. Fix it, and I'll be glad to update my vote.
1

Inside your init you could always do.

self.local_param_1 = self.big_parameter_group.small_parameter_group.param_1

4 Comments

I partially solved this problem by typing, for example, spg = elf.big_parameter_group.small_parameter_group. That partially solves problem - now I must type only spg.param_1, but i'm curious if I can eliminate even spg. Also, usually there are more than 3 parameters, so renaming them all is a bit much boilerplate for me.
@Jakob also note that this will cache the value once, updates won't be received and you also cannot set the value using this method.
@Davy8, 'Cache'ing the value once? That depends entirely on whether the values in question are mutable or immutable; same with 'set'ing it.
@Ethan right, that's why it was a something to note, not necessarily wrong. The OP did not state whether or not the values are immutable so it might not be a safe assumption.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.