1

I'm not sure if I'm asking this correctly, but I know you all are smart enough to figure it out :). I am having trouble condensing some repetitive code in a few python classes. Here is an example of what I mean...

class Parent:

    PATH_PROPERTIES = [ 'parent' ]

    def __init__(self, path):
        self.props = { 'parent': path }

    def getPath(self):
        return self.props['parent']


class Child(Parent):

    PATH_PROPERTIES = [ 'child' ]

    def __init__(self, path):
        self.props = { 'child': path }

    def getPath(self):
        return self.props['child']

Above, is the current situation, but I would like to reduce some of the duplication by doing something like...

class Parent:
    name = 'parent'

    PATH_PROPERTIES = [ name ]

    def __init__(self, path):
        self.props = ( name: path)

    def getPath(self):
        return self.props[name] 

The last bit of code obviously doesn't work. I can't find anything on Python being able to do C++-like macros. What is the best way to condense this code?

2
  • I'm confused. Why are you not using standard class attributes (e.g. Child.path?) Commented Oct 24, 2013 at 21:46
  • 5
    Is there a reason why you need to store the identifiers 'parent' and 'child' as dictionary keys? Some more context would be useful. Commented Oct 24, 2013 at 21:48

2 Answers 2

2

You could use inheritance:

class Parent:

    PATH_PROPERTIES = [ 'parent' ]

    def __init__(self, path):
        self.props = { self.PATH_PROPERTIES[0]: path }

    def getPath(self):
        return self.props[self.PATH_PROPERTIES[0]]


class Child(Parent):

    PATH_PROPERTIES = [ 'child' ]    


c = Child('path')
print(c.getPath())

prints

path

Note that in Python it is usually preferable to use a property instead of a getter function:

class Parent:

    PATH_PROPERTIES = 'parent'

    def __init__(self, path):
        self.props = { self.PATH_PROPERTIES: path }

    @property
    def path(self):
        return self.props[self.PATH_PROPERTIES]


class Child(Parent):

    PATH_PROPERTIES = 'child'         

c = Child('path')
print(c.path)

also prints

path

Note that c.path looks like an attribute lookup, but since path is a property, it calls the function decorated with @property. The syntax looks nicer than c.getPath() and yet gives you the same functionality. There is a decorator to make setters too.

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

1 Comment

Note that you don't need to include an __init__ method in Child if all it's going to do is call the parent class constructor with the same arguments.
1

You should generally be able to do this with standard inheritance with a little redesign (as in unutbu's answer), but you could write a factory function to create your classes. This is probably the closest to what you'd do in C++ with macros:

def make_class(name, base=object):

    class Class(base):

        PATH_PROPERTIES = [name]

        def __init__(self, path):
            self.props = {name: path}

        @property
        def path(self):
            return self.props[name]

    Class.__name__ = name.title()
    return Class

Parent = make_class("parent")
Child  = make_class("child", Parent)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.