Zauważ, że najlepszą praktyką w Pythonie 2.7 jest używanie klas w nowym stylu (niepotrzebnych w Pythonie 3), tj
class Foo(object):
...
Ponadto istnieje różnica między „przedmiotem” a „klasą”. Aby zbudować słownik z dowolnego obiektu , wystarczy użyć __dict__
. Zazwyczaj deklarujesz swoje metody na poziomie klasy, a atrybuty na poziomie instancji, więc __dict__
powinno być dobrze. Na przykład:
>>> class A(object):
... def __init__(self):
... self.b = 1
... self.c = 2
... def do_nothing(self):
... pass
...
>>> a = A()
>>> a.__dict__
{'c': 2, 'b': 1}
Lepszym podejściem (sugerowanym przez Roberta w komentarzach) jest wbudowana vars
funkcja:
>>> vars(a)
{'c': 2, 'b': 1}
Alternatywnie, w zależności od tego, co chcesz zrobić, warto odziedziczyć po nim dict
. Zatem twoja klasa jest już słownikiem i jeśli chcesz, możesz zastąpić getattr
i / lub setattr
zadzwonić i ustawić dyktando. Na przykład:
class Foo(dict):
def __init__(self):
pass
def __getattr__(self, attr):
return self[attr]
# etc...
__dict__
nie będzie działać, jeśli obiekt korzysta ze szczelin (lub zdefiniowanych w module C.)vars(a)
robić? Dla mnie lepiej jest wywoływać__dict__
bezpośrednio.__getattr__ = dict.__getitem__
dokładnie odtworzyć zachowanie, wtedy też chciałbyś__setattr__ = dict.__setitem__
i__delattr__ = dict.__delitem__
dla kompletności.Zamiast tego
x.__dict__
jest w rzeczywistości bardziej pythonowy w użyciuvars(x)
.źródło
MyClass(**my_dict)
, zakładając, że zdefiniowałeś konstruktor z parametrami, które odzwierciedlają atrybuty klasy. Nie trzeba uzyskiwać dostępu do prywatnych atrybutów ani zastępować dyktanda.vars
funkcję i wprowadzić dodatkową funkcjonalność bez zmiany samego obiektu.__slots__
.vars
się, tj. Zwrócenie ekwiwalentu__dict__
dla klas „szczelinowych”. Na razie można go emulować, dodając__dict__
właściwość, która zwraca{x: getattr(self, x) for x in self.__slots__}
(nie wiadomo jednak, czy wpływa to w jakiś sposób na wydajność lub zachowanie).dir
Wbudowane daje wszystkie atrybuty obiektu, w tym specjalnych metod, takich jak__str__
,__dict__
i cała masa innych, które prawdopodobnie nie chcą. Ale możesz zrobić coś takiego:Można więc rozszerzyć tę
props
funkcję, aby zwracała tylko atrybuty danych, a nie metody, definiując swoją funkcję w następujący sposób:źródło
ismethod
nie łapie funkcji. Przykład:inspect.ismethod(str.upper)
.inspect.isfunction
nie jest jednak o wiele bardziej pomocny. Nie jestem pewien, jak podejść do tego od razu.Rozwiązałem kombinację obu odpowiedzi:
źródło
staticmethod
? To nie jestcallable
.Pomyślałem, że poświęcę trochę czasu, aby pokazać, jak można przetłumaczyć obiekt, za pomocą którego można dyktować
dict(obj)
.Kluczową sekcją tego kodu jest
__iter__
funkcja.Jak wyjaśniają komentarze, pierwszą rzeczą, którą robimy, jest chwytanie przedmiotów klasy i zapobieganie czegokolwiek, co zaczyna się od „__”.
Po utworzeniu
dict
możesz użyćupdate
funkcji dict i przekazać instancję__dict__
.To da ci pełny słownik klasy + instancji członków. Teraz pozostaje tylko iterować nad nimi i przynosić zyski.
Ponadto, jeśli planujesz dużo tego używać, możesz stworzyć
@iterable
dekorator zajęć.źródło
dict((x, y) for x, y in KpiRow.__dict__.items() if x[:2] != '__' and not callable(y))
to rozwiąże? Ale wciąż mogą istniećstatic
metody :(Pomija to atrybuty, które obiekt dziedziczy po swojej klasie. Na przykład,
hasattr (a, „x”) jest prawdą, ale „x” nie pojawia się w .__ dict__
źródło
vars()
nie działadir
jest rozwiązaniem w tym przypadku. Zobacz drugą odpowiedź na ten temat.Późna odpowiedź, ale pod warunkiem kompletności i korzyści pracowników Google:
Nie wyświetli to metod zdefiniowanych w klasie, ale nadal pokaże pola, w tym te przypisane do lambdas lub te, które zaczynają się od podwójnego podkreślenia.
źródło
Myślę, że najprostszym sposobem jest utworzenie atrybutu getitem dla klasy. Jeśli chcesz pisać do obiektu, możesz utworzyć niestandardowy setattr . Oto przykład getitem :
dict generuje atrybuty obiektów do słownika, a obiektu słownika można użyć do uzyskania potrzebnego elementu.
źródło
Minusem używania
__dict__
jest to, że jest płytka; nie przekształci żadnych podklas w słowniki.Jeśli używasz języka Python 3.5 lub nowszego, możesz użyć
jsons
:źródło
Jeśli chcesz wyświetlić część swoich atrybutów, zastąp
__dict__
:To bardzo pomaga, jeśli
instance
dostajesz duże dane bloków i chceszd
przesłać do Redis jak kolejka wiadomości.źródło
__dict__
jest atrybutem, a nie metodą, więc ten przykład zmienia interfejs (tzn. musisz wywołać go jako wywołanie), więc nie zastępuje go.PYTHON 3:
Teraz możesz użyć powyższego kodu we własnej klasie:
źródło
vars()
jest świetny, ale nie działa dla zagnieżdżonych obiektów obiektówKonwertuj zagnieżdżony obiekt obiektów na dyktowanie:
źródło