2016-03-18 2 views
1

У меня есть следующий класс:Доступ к атрибутам в классе Python?

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' 

Я не знаю, почему это так. Надеюсь, некоторые другие глаза могут указать, что я делаю неправильно. Спасибо

+0

КСТАТИ Я добавил Q на мета о создании [язычки видимых] (http://meta.stackoverflow.com/questions/319326/make-tabs-actually-visible-in-code- разделы постов) в рендеринге – zmo

ответ

5

У вас смешанные вкладки и пробелы, поэтому определение is_authenticated ошибочно вложено в определение __init__. Включите «show whitespace» в вашем редакторе, чтобы увидеть проблему, и запустите Python с флагом -tt, чтобы он рассказывал вам, когда вы делаете что-то вроде этого. Чтобы устранить проблему, преобразуйте вкладки в пробелы; у вашего редактора, скорее всего, есть функция, чтобы сделать это автоматически.

+0

Спасибо! Это действительно было проблемой, меня почти сбило с ума. – user875139

+0

Как ** ты это понял? Открыв «править», чтобы увидеть, что это вкладка?Я даже не знал, что они сохранены в фактическом коде, потому что выделение фрагмента на странице не дает ясности (если я не пропущу что-то, поэтому я спрашиваю). – dwanderson

+0

yup, вам нужно отредактировать, как на SO, когда код показан, вкладки преобразуются в четыре пробела (просто выберите отступ), тогда как «необработанный» код в окне редактирования сохраняет вкладки. – zmo

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 

все, что является более удобным для чтения и простой в использовании.


NB: для списка dicts для преобразования, просто сделать:

>>> 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__().

НТН

+0

благодарит кучу. Я переработал свой код на что-то подобное. Я все еще получаю зависть от python и некоторых принципов проектирования, поэтому это очень удобно. Кстати, вы знакомы с django? Я просто разместил этот вопрос (http://stackoverflow.com/questions/36092348/custom-authentication-with-custom-user-in-django?noredirect=1#comment59830657_36092348). Пожалуйста, проверьте это, если сможете. – user875139