Jak napisano przed użyciem, obj.__dict__
może obsługiwać typowe przypadki, ale niektóre klasy nie mają __dict__
atrybutu i zastosowania __slots__
(głównie ze względu na wydajność pamięci).
przykład bardziej odpornego sposobu:
class A(object):
__slots__ = ('x', 'y', )
def __init__(self, x, y):
self.x = x
self.y = y
class B(object):
def __init__(self, x, y):
self.x = x
self.y = y
def get_object_attrs(obj):
try:
return obj.__dict__
except AttributeError:
return {attr: getattr(obj, attr) for attr in obj.__slots__}
a = A(1,2)
b = B(1,2)
assert not hasattr(a, '__dict__')
print(get_object_attrs(a))
print(get_object_attrs(b))
wyjście tego kodu:
{'x': 1, 'y': 2}
{'x': 1, 'y': 2}
Uwaga 1:
Python jest językiem dynamicznym i zawsze lepiej jest znać klasy, z których próbujesz uzyskać atrybuty, ponieważ nawet ten kod może przeoczyć niektóre przypadki.
Uwaga 2:
ten kod wyprowadza tylko zmienne instancji, co oznacza, że zmienne klas nie są dostarczane. na przykład:
class A(object):
url = 'http://stackoverflow.com'
def __init__(self, path):
self.path = path
print(A('/questions').__dict__)
kod wyjściowy:
{'path': '/questions'}
Ten kod nie drukuje url
atrybutu klasy i może pomijać pożądane atrybuty klasy.
Czasami możemy myśleć, że atrybut jest członkiem instancji, ale nie jest i nie będzie pokazany na tym przykładzie.
NewClass
. Możesz przeciwstawić się oczekiwaniom ludzi, jeśli zastosujesz taką konwencję nazewnictwanew_class
.