First a general explanation, and then what I am actually working on: Let say you have a group of apples. Some properties could be shared, such as type = "Green Apple" and picked_date = "Aug 12 2012", but other data could be different between apples, such as is_bruised and weight or size. What is the most pythonic way to have editable values shared between apples such as type but also have individual attributes for each apple in the group? Coming from C, C++, my first instinct is a general struct, and a struct for each apple with a pointer to the general struct, as it seems silly for each apple instance to contain the group information, because if I wanted type = "Red Apple" I’d have to iterate though all the apples to edit their type value, which is a waste of programming power.
In real code, on my current work project, I am currently working on a git script to help parse output in a way that makes sense for my company. I have been reading up on (a) lists, (b) tuples, (c) dictionaries, and (d) classes in python, and I am really stuck trying to figure out the best way to represent this data.
To be specific, I am handling git commits, and there are two types of values I am concerned with: general properties shared between all commits, such as “do I print out the author of the commit?”, and specific properties such as “commit x has author y”. My current solution is inelegant:
class Commit(object):
def __init__(self, author="", committer="", date="", issue="",
instruction="", message="", review="", sha="", short=""):
self.author = author
self.committer = committer
self.date = date
self.instruction = instruction
self.issue = issue
self.message = message
self.review = review
self.sha = sha
self.short = short
This class contains the data associated with a specific commit. Now, the data for all commits is stored as such:
Attribute = namedtuple('Attribute', ['display', 'critical'])
commit_attr = {'author': Attribute(display = True, critical = True),
'committer': Attribute(display = True, critical = True),
'date': Attribute(display = False, critical = False),
'instruction': Attribute(display = True, critical = False),
'issue': Attribute(display = True, critical = False),
'message': Attribute(display = True, critical = False),
'review': Attribute(display = True, critical = False),
'sha': Attribute(display = True, critical = True),
'short': Attribute(display = True, critical = True)}
Which is a dictionary with named tuples for the fields. “Critical” indicates if that field is required in a commit for it to be shown, display is used to determine if it should be printed or not.
Here’s my problem: I know that related data in python should be grouped in a coherent method, but I don’t know how to do that here: I could have a “pointer”, such as self.attr = commit_attr in the Commit() class, but this isn’t very clean and would depend on that object keeping its address, i.e. being mutable, otherwise if I changed the value of the general attributes it would no longer be associated with the Commit() class.
I’m not entirely sure if this will be helpful to you, but Python has class attributes, which are shared between class instances:
Editing the class attribute affects all instances at once.