在Python类中访问属性?

时间:2016-03-18 17:25:41

标签: python 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

我正在将dict转换为obj然后尝试访问is_authenticated方法,当我执行以下操作时:

new_array = [{'username': u'rr', 'password': u'something', }]
user = convert_to_obj(new_array)
user.is_authenticated()

它返回错误说:

'convert_to_obj' object has no attribute 'is_authenticated'

我不知道为什么要这样做。希望其他一些人可能能够指出我做错了什么。感谢

2 个答案:

答案 0 :(得分:6)

@ user2357112是对的(好抓,因为我不会看到它):

DO NOT USE TABS IN PYTHON ­— EVER!

那就是说,我对你的代码有一些评论。

首先:

class convert_to_obj(object):

是一个非常糟糕的类名。不过,这对于一个功能来说是个好名字。你应该更好地称呼它,例如:

class DictObject(object):

话虽这么说,我建议你使用现有工具来做这样的事情。在collections模块中有一个名为namedtuple的强大功能。做你的事,你可以这样做:

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)

会给出:

>>> 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

所有这些都更具可读性和易用性。

N.B。:要转换的dicts列表,只需make:

>>> objdict_list = [convert_to_object(d) for d in new_array]
>>> objdict_list
[DictObject(password='something', username='rr')]

如果您正在使用对列表而不是字典:

>>> tup_array = [('username', u'rr'), ('password', u'something')]
>>> {t[0]:t[1] for t in tup_array}
{'password': 'something', 'username': 'rr'}

所以你不需要__init__()中的额外腿部工作。

HTH

答案 1 :(得分:5)

您混合了标签和空格,因此is_authenticated定义错误地嵌套在__init__的定义中。打开"显示空白"在您的编辑器中查看问题,并使用-tt标志运行Python,以便在您执行此类操作时告诉您。要解决此问题,请将选项卡转换为空格;您的编辑器很可能具有自动执行此操作的功能。