2016-03-18 19 views
1

Ich habe die folgende Klasse:Zugreifen auf Attribute in Python-Klasse?

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 

Ich bin ein dict obj Umwandlung und dann die is_authenticated Methode zuzugreifen versuchen, wenn ich folgendes tun unten:

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

es gibt eine Fehlermeldung, :

'convert_to_obj' object has no attribute 'is_authenticated' 

Ich weiß nicht, warum es das tut. Hoffentlich können einige andere Augen darauf hinweisen, was ich falsch mache. Danke

+0

BTW ein Q auf Meta Ich habe darüber machen [sichtbar Tabs] hinzugefügt (http://meta.stackoverflow.com/questions/319326/make-tabs-actually-visible-in-code- Post-Sektionen) in gerenderten Abschriften – zmo

Antwort

5

Sie haben Registerkarten und Leerzeichen gemischt, so dass die is_authenticated Definition fälschlicherweise innerhalb der Definition von __init__ verschachtelt ist. Aktivieren Sie "show whitespace" in Ihrem Editor, um das Problem zu sehen, und führen Sie Python mit dem -tt Flag aus, damit es Ihnen sagt, wenn Sie so etwas tun. Konvertieren Sie die Registerkarten in Leerzeichen, um das Problem zu beheben. Ihr Editor hat höchstwahrscheinlich eine Funktion, um dies automatisch zu tun.

+0

Danke! Das war tatsächlich das Thema, das mich fast verrückt machte. – user875139

+0

Wie ** hast du das gesehen? Indem Sie die 'edit' öffnen, um zu sehen, dass es sich um eine Registerkarte handelt?Ich wusste nicht einmal, dass diese im tatsächlichen Code beibehalten wurden, weil das Hervorheben des Snippets auf der Seite es nicht klar macht (es sei denn, ich verpasse etwas, weshalb ich darum bitte). – dwanderson

+0

yup, Sie müssen bearbeiten, wie auf SO, wenn der Code angezeigt wird, werden die Registerkarten in vier Leerzeichen konvertiert (nur die Einrückung auswählen), während der "rohe" Code im Bearbeitungsfeld Registerkarten enthält. – zmo

6

@ user2357112 richtig ist (und guten Fang, weil ich es nicht gesehen hätte):

DO NOT USE TABS IN PYTHON ­— EVER!

Das heißt, ich habe ein paar Kommentare über Ihren Code.

Erstens:

class convert_to_obj(object): 

ist ein sehr schlechter Name für eine Klasse. Es wäre jedoch ein guter Name für eine Funktion. Sie sollten es besser nennen, zum Beispiel:

class DictObject(object): 

aber sagen, dass ich Ihnen raten würde vorhandenen Werkzeuge zu verwenden, um so etwas zu tun. Im Modul collections gibt es einen leistungsfähigen Baustein namens namedtuple. Um Ihre Sache zu tun, könnten Sie tun:

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) 

, die geben würde:

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

alles, was sein besser lesbar und leicht zu bedienen.


NB: Eine Liste des dicts zu konvertieren, so stellen:

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

Und wenn Sie mit einer Liste von Paaren statt einem dict arbeiten:

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

Sie brauchen also nicht die zusätzliche Beinarbeit im __init__().

HTH

+0

danke ein Haufen. Ich habe meinen Code auf etwas Ähnliches umgestaltet. Ich habe immer noch den Python und einige Designprinzipien im Griff, so dass es praktisch ist. Übrigens kennst du Django? Ich habe gerade diese Frage gestellt (http://stackoverflow.com/questions/36092348/custom-authentication-with-custom-user-in-django?noredirect=1#comment59830657_36092348). Bitte überprüfen Sie es, wenn Sie können. – user875139

Verwandte Themen