2016-10-02 4 views
0

Benutzerdaten wie folgt:Wenn eine Klasse zu verwenden, anstatt ein dict

user = {"id": 1, "firstName": "Bar", "surname": "Foosson", "age": 20} 

zu einer Anwendung über json gesendet wird.

In vielen Stellen im Code folgend getan:

user["firstName"] + " " + user["surname"] 

, die mich eine Funktion führt zu glauben, verwendet werden soll:

def name(user): 
    return user["firstName"] + " " + user["surname"] 

was wiederum führt mich, dass der Code zu glauben, sollte stattdessen unter Verwendung einer User Klasse mit einer name Methode refaktoriert werden. Stimmen Sie zu und gibt es Argumente dafür, den Code nicht zu refaktorisieren, um stattdessen eine Klasse zu verwenden?

+3

Abgesehen, Verwenden '" {firstname} { Nachname} ". Format (** Benutzer)'. ;) –

+0

Noch eine andere Seite: In Python werden diese Dinge "dicts" genannt (ihr Typ ist 'dict'); sie "Karten" zu nennen, kann verwirrend sein (wegen 'Karte'). –

+2

Ich würde eine Klasse verwenden, auch wenn es keinen 'def name (user)' braucht. Wenn die Schlüssel des 'dict' fest sind (Sie erwarten immer Vorname, Nachname), ist das ein Hinweis darauf, dass Sie wahrscheinlich kein' dict' verwenden sollten. – zvone

Antwort

1

Ich bin sicher, dass Sie zögern, Klassen zu verwenden, weil Sie den Code schreiben müssen.

Aber es gibt eine nette Bibliothek, die Ihnen das Leben erleichtern kann: attrs.

Glyph hat einen Beitrag mit einem selbstsprechenden Titel: The One Python Library Everyone Needs. Natürlich ist es ein meinungs Stück, aber hier ist ein Zitat aus seinem Examples page:

>>> @attr.s 
... class Coordinates(object): 
...  x = attr.ib() 
...  y = attr.ib() 

Standardmäßig werden alle Funktionen hinzugefügt, so dass Sie sofort eine voll funktionsfähige Datenklasse mit einem schönen repr String und Vergleichsmethoden haben .

>>> c1 = Coordinates(1, 2) 
>>> c1 
Coordinates(x=1, y=2) 
>>> c2 = Coordinates(x=2, y=1) 
>>> c2 
Coordinates(x=2, y=1) 
>>> c1 == c2 
False 

Es ist eine ganz praktisch Bibliothek, so check it out.

Hier ist ein Beispiel für Ihre User Klasse:

import attr 

@attr.s 
class User(object): 

    id = attr.ib() 
    firstName = attr.ib() 
    surname = attr.ib() 
    age = attr.ib() 

    @property 
    def name(self): 
     return '{0.firstName} {0.surname}'.format(self) 

user_dict = {'id': 1, 'firstName': 'Bar', 'surname': 'Foosson', 'age': 20} 
user = User(**user_dict) 
assert user.name == 'Bar Foosson' 
1

Wörterbücher sind für die Speicherung und den Abruf, aber wenn Sie mehr Funktionalität obendrein müssen, eine Klasse ist in der Regel der Weg zu gehen. Auf diese Weise können Sie auch sicherstellen, dass bestimmte Attribute gesetzt sind usw.

Wenn in Ihrer Situation die Attribute eines Benutzers schreibgeschützt sind, würde mein Ansatz tatsächlich namedtuple verwenden. Sie erhalten Unveränderlichkeit von Attributen, Speichereffizienz und Sie können einstellen, nach wie vor name zu einem vordefinierten Verfahren nur verwendet werden, wie Sie property auf eine Klasse verwenden würde:

from collections import namedtuple 

@property 
def name(self): 
    return '{} {}'.format(self.firstName, self.surname) 

User = namedtuple('User', 'id firstName surname age') 
User.name = name 

user = User(1, 'Bar', 'Foosson', 20) 
print(user.name) # Bar Foosson 

user = User(2, 'Another', 'Name', 1) 
print(user.name) # Another Name 
Verwandte Themen