У меня есть объект Python с несколькими атрибутами и методами. Я хочу перебрать атрибуты объекта.
class my_python_obj(object):
attr1='a'
attr2='b'
attr3='c'
def method1(self, etc, etc):
#Statements
Я хочу создать словарь, содержащий все атрибуты объектов и их текущие значения, но я хочу сделать это динамически (поэтому, если позже я добавлю другой атрибут, мне не придется также обновлять свою функцию).
В php переменные могут использоваться как ключи, но объекты в python неприемлемы, и если я использую для этого точечную нотацию, он создает новый атрибут с именем моего var, который не является моим намерением.
Просто чтобы прояснить ситуацию:
def to_dict(self):
'''this is what I already have'''
d={}
d["attr1"]= self.attr1
d["attr2"]= self.attr2
d["attr3"]= self.attr3
return d
·
def to_dict(self):
'''this is what I want to do'''
d={}
for v in my_python_obj.attributes:
d[v] = self.v
return d
Обновление: под атрибутами я подразумеваю только переменные этого объекта, а не методы.
python
oop
attributes
iteration
Пабло Мешер
источник
источник
predicate
аргумент для передачи вызываемого объекта, который отфильтровывал бы (связывал?) функции (который избавлялся от методов).Ответы:
Предполагая, что у вас есть такой класс, как
вызов
dir
объекта возвращает все атрибуты этого объекта, включая специальные атрибуты python. Хотя некоторые атрибуты объекта могут вызываться, например методы.Вы всегда можете отфильтровать специальные методы, используя понимание списка.
или если вы предпочитаете карту / фильтры.
Если вы хотите отфильтровать методы, вы можете использовать встроенный
callable
в качестве проверки.Вы также можете проверить разницу между вашим классом и его экземпляром объекта с помощью.
источник
callable
илиtypes.MethodType
. Что произойдет, если я добавлю атрибут «_foo», в котором будет сохранен какой-то промежуточный результат или внутренняя структура данных? Что произойдет, если я просто добавлю атрибут в классname
, скажем, и теперь он вдруг включается._foo
иname
потому что они теперь являются атрибутами объекта. Если вы не хотите включать их, вы можете исключить их из условия понимания списка. Приведенный выше код является распространенной идиомой Python и популярным способом анализа объектов Python.dir()
только "лежит", когда переданы метаклассы (крайний крайний случай) или классы с атрибутами, украшенными@DynamicClassAttribute
(другой крайний крайний случай). В обоих случаях вызовdirs()
оберткиinspect.getmembers()
решает эту проблему. Однако для стандартных объектов этого подхода к пониманию списков для фильтрации не подлежащих вызову абсолютно достаточно. То, что некоторые питонисты назвали бы это «плохой идеей», сбивает меня с толку, но ... каждому, я полагаю, свое собственное?в общем, поместите
__iter__
метод в ваш класс и итерируйте атрибуты объекта или поместите этот класс mixin в свой класс.Твой класс:
источник
one
иtwo
определено послеyc = YourClass()
. Вопрос спрашивает о перекручивание через существующие attris вYourClass()
. Кроме того, наследованиеIterMixin
класса не всегда доступно в качестве решения.vars(yc)
дает тот же результат без необходимости наследования от другого класса.vars(yc)
почти такой же, но словарь, который он вам возвращает, является собственным экземпляром__dict__
, поэтому изменение его будет отражено в экземпляре. Это может привести к проблемам, если вы не будете осторожны, поэтому вышеописанный метод иногда может быть лучше (хотя копирование словаря, вероятно, проще). Кроме того, обратите внимание, что хотя приведенный выше словарь не является экземпляром экземпляра__dict__
, значения одинаковы, поэтому изменение любых изменяемых значений все равно будет отражено в атрибутах экземпляра.Как уже упоминалось в некоторых ответах / комментариях, объекты Python уже хранят словарь своих атрибутов (методы не включены). Это может быть доступно как
__dict__
, но лучший способ - использоватьvars
(хотя вывод тот же). Обратите внимание, что изменение этого словаря изменит атрибуты экземпляра! Это может быть полезно, но также означает, что вы должны быть осторожны с тем, как вы используете этот словарь. Вот быстрый пример:Использование
dir(a)
- странный, если не откровенный, плохой подход к этой проблеме. Хорошо, если вам действительно нужно перебрать все атрибуты и методы класса (включая специальные методы, например__init__
). Тем не менее, это не то, что вам нужно, и даже принятый ответ идет плохо, применяя хрупкую фильтрацию, чтобы попытаться удалить методы и оставить только атрибуты; Вы можете увидеть, как это не получится для класса,A
определенного выше.(Использование
__dict__
было сделано в нескольких ответах, но все они определяют ненужные методы вместо того, чтобы использовать его напрямую. Только комментарий предлагает использоватьvars
).источник
a.b
какой-то пользовательский класс,B
тоvars(a)["b"] is a.b
, как и следовало ожидать; ничто иное не имело бы смысла (считалосьa.b
синтаксическим сахаромa.__dict__["b"]
). Если у вас естьd = vars(a)
и call,repr(d)
то он будет вызыватьrepr(d["b"])
как часть возврата своей собственной строки repr, так как только классB
действительно знает, как она должна быть представлена в виде строки.Объекты в python хранят свои атрибуты (в том числе функции) в вызываемом слове
__dict__
. Вы можете (но обычно не должны) использовать это для прямого доступа к атрибутам. Если вы просто хотите получить список, вы также можете вызватьdir(obj)
, который возвращает итерацию со всеми именами атрибутов, которые вы можете затем передатьgetattr
.Однако необходимость что-либо делать с именами переменных, как правило, плохой дизайн. Почему бы не хранить их в коллекции?
Затем вы можете перебирать ключи с помощью
for key in obj.special_values:
источник
тогда просто назовите это как итеративный
источник
Правильный ответ на это, что вы не должны. Если вам нужен этот тип вещей, либо просто используйте dict, либо вам нужно явно добавить атрибуты в некоторый контейнер. Вы можете автоматизировать это, узнав о декораторах.
В частности, кстати, method1 в вашем примере так же хорош как атрибут.
источник
Для питона 3.6
источник
Я уверен, что для всех питонских фанатиков Йохан Клиз одобрит ваш догматизм;). Я оставляю этот ответ, продолжайте его унизлять. Это на самом деле делает меня более доверенным. Оставьте комментарий вам, цыплята!
Для питона 3.6
источник