Last active
August 29, 2015 14:03
-
-
Save azalea/405322f5846b0da568ba to your computer and use it in GitHub Desktop.
Use getattr() to access any attribute of any class instance
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Say I have such classes A, B, C, ..., Y, and Z that do different things, | |
# and classes AComment, BComment, CComment, ..., YComment and ZComment | |
# that record comments on instances of class A, B, ..., Y and Z respectively. | |
# All XComment classes share the same attributes except one property | |
# that is is dependent on the class the comment is for. | |
# e.g. AComment has a property 'a' and BComment has a property 'b'. | |
class A(): | |
def __init__(self): | |
print 'init an instance of class A' | |
# do_some_A_stuff() | |
def __str__(self): | |
return 'an instance of class A' | |
class B(): | |
def __init__(self): | |
print 'init an instance of class B' | |
# do_some_B_stuff() | |
def __str__(self): | |
return 'an instance of class B' | |
class Z(): | |
def __init__(self): | |
print 'init an instance of class Z' | |
# do_some_Z_stuff() | |
def __str__(self): | |
return 'an instance of class Z' | |
class AComment(): | |
def __init__(self, a_instance, comment): | |
self.a = a_instance | |
self.comment = comment | |
class BComment(): | |
def __init__(self, b_instance, comment): | |
self.b = b_instance | |
self.comment = comment | |
class ZComment(): | |
def __init__(self, z_instance, comment): | |
self.z = z_instance | |
self.comment = comment | |
# I'd like to create different XComment Instance given a user preference. For example | |
# If preference == 'apple', create AComment. | |
# If preference == 'banana', create BComment. | |
# If preference == 'cucumber', create CComment. | |
# ... | |
# If preference == 'zucchini', create ZComment. | |
# One way of doing this: | |
def create_xcomment(preference): | |
if preference == 'apple': | |
a_instance = A() | |
a_comment = AComment(a_instance, 'comment to A') | |
print a_comment.a | |
print a_comment.comment | |
# a lot of other code dependent on classes A and AComment | |
elif preference == 'banana': | |
b_instance = B() | |
b_comment = BComment(b_instance, 'comment to B') | |
print b_comment.b | |
print b_comment.comment | |
# a lot of other code repeated, dependent on classes B and BComment | |
# elif preference == 'cucumber': | |
# ... | |
# a lot of other code repeated a 3rd time, dependent on classes C and CComment | |
# ... | |
elif preference == 'zucchini': | |
z_instance = Z() | |
z_comment = ZComment(z_instance, 'comment to Z') | |
# a lot of other code repeated a 26th time, dependent on classes Z and ZComment | |
# Another way of doing this: | |
def create_xcomment2_worker(MyClass, MyCommentClass, comment_class_attribute): | |
my_instance = MyClass() | |
my_comment = MyCommentClass(my_instance, 'comment to %s'%MyClass.__name__) | |
print getattr(my_comment, comment_class_attribute) # the comment_class_attribute is different for different XClass. | |
print my_comment.comment # the 'comment' property has the same name across all XComment classes. | |
# a lot of other code | |
def create_xcomment2(preference): | |
if preference == 'apple': | |
create_xcomment2_worker(MyClass=A, MyCommentClass=AComment, comment_class_attribute='a') | |
elif preference == 'banana': | |
create_xcomment2_worker(MyClass=B, MyCommentClass=BComment, comment_class_attribute='b') | |
# elif preference == 'cucumber': | |
# ... | |
elif preference == 'zucchini': | |
create_xcomment2_worker(MyClass=Z, MyCommentClass=ZComment, comment_class_attribute='z') | |
# The following gives the same result, but the code for the latter is much shorter | |
create_xcomment('banana') | |
create_xcomment2('banana') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment