I have the following class:
class convert_to_obj(object):
def __init__(self, d):
for llist in d:
for a, b in llist.items():
if isinstance(b, (list, tuple)):
setattr(self, a, [obj(x) if isinstance(x, dict) else x for x in b])
else:
setattr(self, a, obj(b) if isinstance(b, dict) else b)
def is_authenticated(self):
username = self.username
password = self.password
if username and password:
return True
I am converting a dict to obj and then trying to access the is_authenticated method, when I do the following below:
new_array = [{'username': u'rr', 'password': u'something', }]
user = convert_to_obj(new_array)
user.is_authenticated()
it returns an error saying:
'convert_to_obj' object has no attribute 'is_authenticated'
I don't know why it's doing this. Hopefully, some other eyes might be able to point out what I am doing wrong. Thanks
@user2357112 is right (and good catch, because I wouldn't have seen it):
That said, I have a few comments about your code.
First:
class convert_to_obj(object):
is a very bad name for a class. It'd be a good name for a function, though. You should better call it, for example:
class DictObject(object):
That being said, I'd advice you to use existing tools for doing such a thing. There's a powerful one called namedtuple
, in the collections
module. To do your thing, you could do:
from collections import namedtuple
# Create a class that declares the interface for a given behaviour
# which will expect a set of members to be accessible
class AuthenticationMixin():
def is_authenticated(self):
username = self.username
password = self.password
# useless use of if, here you can simply do:
# return username and password
if username and password:
return True
# but if you don't, don't forget to return False below
# to keep a proper boolean interface for the method
return False
def convert_to_object(d): # here that'd be a good name:
# there you create an object with all the needed members
DictObjectBase = namedtuple('DictObjectBase', d.keys())
# then you create a class where you mix the interface with the
# freshly created class that will contain the members
class DictObject(DictObjectBase, AuthenticationMixin):
pass
# finally you build an instance with the dict, and return it
return DictObject(**d)
which would give:
>>> new_array = [{'username': u'rr', 'password': u'something', }]
>>> # yes here I access the first element of the array, because you want
>>> # to keep the convert_to_object() function simple.
>>> o = convert_to_object(new_array[0])
>>> o
DictObject(password='something', username='rr')
>>> o.is_authenticated()
True
all that being more readable and easy to use.
NB: for a list of dicts to convert, just make:
>>> objdict_list = [convert_to_object(d) for d in new_array]
>>> objdict_list
[DictObject(password='something', username='rr')]
And if you're working with a list of pairs instead of a dict:
>>> tup_array = [('username', u'rr'), ('password', u'something')]
>>> {t[0]:t[1] for t in tup_array}
{'password': 'something', 'username': 'rr'}
So you don't need the extra leg work in the __init__()
.
HTH
You've mixed tabs and spaces, so the is_authenticated
definition is erroneously nested inside the definition of __init__
. Turn on "show whitespace" in your editor to see the problem, and run Python with the -tt
flag to make it tell you when you do something like this. To fix the problem, convert the tabs to spaces; your editor most likely has a function to do this automatically.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.