Reputation: 1390
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?
Upvotes: 1
Views: 153
Reputation: 880677
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.
Upvotes: 2
Reputation: 184345
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)
Upvotes: 1