Есть ли в Python встроенный метод для получения массива всех переменных экземпляра класса? Например, если у меня есть этот код:
class hi:
def __init__(self):
self.ii = "foo"
self.kk = "bar"
Есть ли у меня способ сделать это:
>>> mystery_method(hi)
["ii", "kk"]
Обновлено: изначально я ошибочно запрашивал переменные класса.






У каждого объекта есть переменная __dict__, содержащая все переменные и ее значения.
Попробуй это
>>> hi_obj = hi()
>>> hi_obj.__dict__.keys()
FWIW, модуль проверки дает вам более надежный метод, чем полагаться на диктовать, который есть не во всех экземплярах.
У какого экземпляра нет диктовать? Никогда не встречал.
Некоторые встроенные типы, например int. Попробуйте сказать «x = 5», а затем «x .__ dict__», и вы получите AttributeError.
Также все, что использует слоты.
Зачем вам пытаться получить переменные экземпляра класса int? Это даже не класс (хотя я могу ошибаться в этом).
Также re.MatchObjects (без __dict__)
@MartinSherburn Потому что кто-то может захотеть получить переменные экземпляров, заранее зная, какие типы будут встречаться.
Как выглядит пример вывода для этого кода?
Также numpy ndarrays возвращает AttributeError, когда вы пытаетесь получить доступ к их атрибутам с помощью __dict__
Обычно вы не можете получить атрибуты экземпляра, заданные только классом, по крайней мере, без создания экземпляра класса. Однако вы можете получить атрибуты экземпляра для данного экземпляра или атрибуты класса для класса. См. Модуль «инспектировать». Вы не можете получить список атрибутов экземпляра, потому что экземпляры действительно могут иметь что угодно в качестве атрибута, и - как в вашем примере - обычный способ их создания - просто назначить им в методе __init__.
Исключением является случай, если ваш класс использует слоты, которые представляют собой фиксированный список атрибутов, которые класс разрешает иметь экземплярам. Слоты объясняются в http://www.python.org/2.2.3/descrintro.html, но со слотами есть различные подводные камни; они влияют на структуру памяти, поэтому множественное наследование может быть проблематичным, и при наследовании в целом также необходимо учитывать слоты.
Голосование вниз, потому что «вы не можете получить список атрибутов экземпляра», просто неверно: и vars (), и диктовать дают вам именно это.
Я предполагаю, что он имел в виду «вы не можете получить список всех возможных атрибутов экземпляра». Например, я часто использую ленивую генерацию и декоратор @property для добавления переменной экземпляра при первом запросе. Использование диктовать сообщит вам об этой переменной, когда она существует, но не заранее.
Я не голосовал против, и обратите внимание на то, что я на самом деле сказал: вы не можете получить список атрибутов экземпляра учитывая просто класс, что и пытается сделать код, сопровождающий вопрос.
@Carl: Пожалуйста, учитесь перед тем, как писать ложные комментарии и голосовать против, исходя из вашего незнания.
Вы также можете проверить, есть ли у объекта конкретная переменная:
>>> hi_obj = hi()
>>> hasattr(hi_obj, "some attribute")
В вашем примере показаны «переменные экземпляра», а не переменные класса.
Найдите в hi_obj.__class__.__dict__.items() переменные класса, а также другие члены класса, такие как функции-члены и содержащий модуль.
class Hi( object ):
class_var = ( 23, 'skidoo' ) # class variable
def __init__( self ):
self.ii = "foo" # instance variable
self.jj = "bar"
Переменные класса используются всеми экземплярами класса.
Используйте vars ()
class Foo(object):
def __init__(self):
self.a = 1
self.b = 2
vars(Foo()) #==> {'a': 1, 'b': 2}
vars(Foo()).keys() #==> ['a', 'b']
+1 Я лично считаю, что этот синтаксис чище, чем использование диктовать, поскольку атрибуты с двойным подчеркиванием должны быть «частными» в синтаксисе Python.
@Martin: __method является частным, __method__ - специальным методом, не обязательно частным; Я хотел бы сказать, что специальные методы определяют возможности объекта, а не методы.
__method__ довольно уродлив, и я думаю, что они были названы так, чтобы попытаться удержать людей от их использования без крайней необходимости. В этом случае у нас есть альтернативный вариант vars ().
в моем случае я попытался вызвать vars (ObjName), и он возвращает dict_proxy со словарем, ключи которого являются методами данного класса / объекта, но без признаков элементов в этом. Есть догадки, почему?
Переменные двойного подчеркивания __str__, __method__ обычно относятся к самому языку. Что происходит при использовании str(something)?
Предложить
>>> print vars.__doc__
vars([object]) -> dictionary
Without arguments, equivalent to locals().
With an argument, equivalent to object.__dict__.
Другими словами, он просто обертывает __dict__
Хотя это и не прямой ответ на вопрос OP, есть довольно приятный способ узнать, какие переменные находятся в области видимости функции. взгляните на этот код:
>>> def f(x, y):
z = x**2 + y**2
sqrt_z = z**.5
return sqrt_z
>>> f.func_code.co_varnames
('x', 'y', 'z', 'sqrt_z')
>>>
Атрибут func_code содержит много интересного. Это позволяет делать классные вещи. Вот пример того, как я это использовал:
def exec_command(self, cmd, msg, sig):
def message(msg):
a = self.link.process(self.link.recieved_message(msg))
self.exec_command(*a)
def error(msg):
self.printer.printInfo(msg)
def set_usrlist(msg):
self.client.connected_users = msg
def chatmessage(msg):
self.printer.printInfo(msg)
if not locals().has_key(cmd): return
cmd = locals()[cmd]
try:
if 'sig' in cmd.func_code.co_varnames and \
'msg' in cmd.func_code.co_varnames:
cmd(msg, sig)
elif 'msg' in cmd.func_code.co_varnames:
cmd(msg)
else:
cmd()
except Exception, e:
print '\n-----------ERROR-----------'
print 'error: ', e
print 'Error proccessing: ', cmd.__name__
print 'Message: ', msg
print 'Sig: ', sig
print '-----------ERROR-----------\n'
Оба метода Vars () и dict будут работать для примера, опубликованного OP, но они не будут работать для "слабо" определенных объектов, таких как:
class foo:
a = 'foo'
b = 'bar'
Чтобы распечатать все невызываемые атрибуты, вы можете использовать следующую функцию:
def printVars(object):
for i in [v for v in dir(object) if not callable(getattr(object,v))]:
print '\n%s:' % i
exec('print object.%s\n\n') % i
exec('print object.%s\n\n') % i должен быть записан как print getattr(object, i).
построен на ответе dmark, чтобы получить следующее, что полезно, если вам нужен эквивалент sprintf и, надеюсь, поможет кому-то ...
def sprint(object):
result = ''
for i in [v for v in dir(object) if not callable(getattr(object, v)) and v[0] != '_']:
result += '\n%s:' % i + str(getattr(object, i, ''))
return result
Иногда вам нужно отфильтровать список на основе общедоступных / частных переменных. Например.
def pub_vars(self):
"""Gives the variable names of our instance we want to expose
"""
return [k for k in vars(self) if not k.startswith('_')]
Вам потребуется сначала изучить класс, затем проверить байт-код на наличие функций, затем скопировать байт-код и, наконец, используйте __code__.co_varnames. Это сложно, потому что некоторые классы создают свои методы с помощью конструкторов, подобных тем, что используются в модуле types.. Я предоставлю его код на GitHub.
В вашем примере показаны «переменные экземпляра». Другое дело - переменные класса.