patternpythonMinor
Agnostic means of identifying a member
Viewed 0 times
meansmemberidentifyingagnostic
Problem
I'm attempting to provide an agnostic means of identifying a member. I need a
There is a circumstance in my application in which actual
The problem is in attempting to not care about its type. I've gone to the extent of trying attributes and items, and now my code looks incredibly repetitive.
The question is, if my attempts to not care about the type to this extent are reasonable, then is there a way
nickname, a guid, and one of user_id, email, or phone_number. Since I'm using Python, I try to not care about the Python type of member because, after all, if it has what I'm looking for then I don't really care whether it really is a Member... or so I have been taught.There is a circumstance in my application in which actual
Member instances may be lumped in with objects that represent the information necessary to create a member. Also, note that actual Member instances have a handy identification() method, which my code tries first.The problem is in attempting to not care about its type. I've gone to the extent of trying attributes and items, and now my code looks incredibly repetitive.
try:
return member.identification()
except AttributeError:
pass
id_types = ['user_id', 'email', 'phone_number']
if isinstance(member, dict):
if 'guid' not in member:
member['guid'] = cls._next_guid()
for idt in id_types:
if idt in member:
try:
return {
'nickname': member['nickname'],
'guid': member['guid'],
idt: member[idt]
}
except KeyError:
raise ValueError('no nickname')
else:
raise ValueError('no user_id, email, or phone_number')
else:
if 'guid' not in member:
member['guid'] = cls._next_guid()
for idt in id_types:
if hasattr(member, idt):
try:
return {
'nickname': member.nickname,
'guid': member.guid,
idt: getattr(member, idt)
}
except AttributeError:
raise ValueError('no nickname')
raise ValueError('no identification could be made')The question is, if my attempts to not care about the type to this extent are reasonable, then is there a way
Solution
I see 2 approaches to this:
If you proceed by approach 1, then your resulting code will be very concise:
But you will have a lot of additional logic in
Alternatively, if you do not like that approach, we can make
We can do this by adding some magic methods to
This would make code snippet something like this:
- Allow
Memberto be initialized with a dictionary.
- Allow your
Memberclass to behave like a dictionary.
If you proceed by approach 1, then your resulting code will be very concise:
if isinstance(member, Member):
return member.identification()
else if isinstance(member, dict):
member = Member(member)
return member.identification()
raise ValueError('no identification could be made')But you will have a lot of additional logic in
MemberAlternatively, if you do not like that approach, we can make
Member work like a dictionary. Basically member['guid'] would refer to member.guid if member is a Member or the dictionary version if member is a dictionary.We can do this by adding some magic methods to
Member: __getitem__(self, key): and __setitem__(self, key, val): and __contains__(self, val):. The code would look something like this:def __getitem__(self, key):
if key == "nickname":
return self.nickname
elif key == "guid":
return self.guid
# and so on
def __setitem(self, key, val):
if key == "nickname":
self.nickname = val
elif key == "guid":
self.guid = val
# and so on
def __contains__(self, val):
if val == "guid":
return self.guid != None
elif val == "user_id":
return self.user_id != None
# and so onThis would make code snippet something like this:
try:
return member.identification()
except AttributeError:
pass
if not isinstance(member, Member) and not isinstance(member, dict):
raise ValueError('no identification could be made')
id_types = ['user_id', 'email', 'phone_number']
if 'guid' not in member:
member['guid'] = cls._next_guid()
for idt in id_types:
if idt in member:
try:
return {
'nickname': member['nickname'],
'guid': member['guid'],
idt: member[idt]
}
except KeyError:
raise ValueError('no nickname')
else:
raise ValueError('no user_id, email, or phone_number')Code Snippets
if isinstance(member, Member):
return member.identification()
else if isinstance(member, dict):
member = Member(member)
return member.identification()
raise ValueError('no identification could be made')def __getitem__(self, key):
if key == "nickname":
return self.nickname
elif key == "guid":
return self.guid
# and so on
def __setitem(self, key, val):
if key == "nickname":
self.nickname = val
elif key == "guid":
self.guid = val
# and so on
def __contains__(self, val):
if val == "guid":
return self.guid != None
elif val == "user_id":
return self.user_id != None
# and so ontry:
return member.identification()
except AttributeError:
pass
if not isinstance(member, Member) and not isinstance(member, dict):
raise ValueError('no identification could be made')
id_types = ['user_id', 'email', 'phone_number']
if 'guid' not in member:
member['guid'] = cls._next_guid()
for idt in id_types:
if idt in member:
try:
return {
'nickname': member['nickname'],
'guid': member['guid'],
idt: member[idt]
}
except KeyError:
raise ValueError('no nickname')
else:
raise ValueError('no user_id, email, or phone_number')Context
StackExchange Code Review Q#60763, answer score: 4
Revisions (0)
No revisions yet.