Как получить все объекты в модуле в Python? - PullRequest
13 голосов
/ 03 апреля 2011

Мне нужно получить список всех объектов в модуле, а не список только их имен. Так, например, у меня есть:

class myClass:  
    def __init__(self):  
        # here be code
        pass

class thing1(myClass):  
    def __init__(self):  
        self.x = 1

class thing2(myClass):  
    def __init__(self):
        self.x = 2

и так далее.

То, что я хочу, это то, что даст мне список объектов в myClass (thing1, thing2), из которого я могу вызывать методы / получать атрибуты. Я пытаюсь сделать что-то вроде этого:

for myThing in dir(myClass):  
    print myThing.x

Но функция dir дает только список имен классов, и я не могу получить атрибут из этого.

Как я могу это сделать?

Ответы [ 6 ]

19 голосов
/ 03 апреля 2011

Если у вас есть имя атрибута в строке, вы должны использовать getattr для его извлечения.

Имея модуль X, вы можете получить список всех его атрибутов и (например) их типов с чем-то вроде этого.

for i in dir(X):
   print i,"  ",type(getattr(X,i))
7 голосов
/ 04 апреля 2011

Если вы действительно хотите членов класса, экземпляра или модуля, просто используйте встроенный vars(): http://docs.python.org/library/functions.html#vars (он работает как объявлено)

Если вы хотите, чтобы члены текущего модуля находились внутри функции или класса (где vars() будет делать неправильные вещи), тогда вам следует использовать globals().

Однако код и слова в вашем вопросе не совпадают. Вы говорите , что вам нужен доступ к объектам "внутри" myClass, но затем вы публикуете код, который явно ищет подклассы myClass, а не его содержимое.

Чтобы дополнить ответы Asterisk еще несколькими примерами игры в интерактивном режиме:

>>> class Example:
...   def method(): pass
...
>>> class SubExample(Example):
...   pass
...
>>> class OverrideExample(Example):
...   def method():
...     pass
...
>>> globals()
{'OverrideExample': <class '__main__.OverrideExample'>, '__builtins__': <module
'builtins' (built-in)>, 'Example': <class '__main__.Example'>, '__name__': '__ma
in__', '__package__': None, '__doc__': None, 'SubExample': <class '__main__.SubE
xample'>}
>>> Example.__subclasses__()
[<class '__main__.SubExample'>, <class '__main__.OverrideExample'>]
>>> vars(Example)
dict_proxy({'__dict__': <attribute '__dict__' of 'Example' objects>, '__module__
': '__main__', '__weakref__': <attribute '__weakref__' of 'Example' objects>, 'm
ethod': <function method at 0x00BF6F18>, '__doc__': None})
>>> vars(SubExample)
dict_proxy({'__module__': '__main__', '__doc__': None})
>>> vars(OverrideExample)
dict_proxy({'__module__': '__main__', 'method': <function method at 0x00C10030>,
 '__doc__': None})
>>> vars(Example())
{}
>>> vars(SubExample())
{}
>>> vars(OverrideExample())
{}

Обратите внимание на различия между тем, что видно на уровне модуля, в каждом объекте класса и в каждом экземпляре класса.

Также обратите внимание, что для данного определения класса vars() не будет сообщать вам о любых унаследованных методах. Он также не расскажет вам о методах, доступных через экземпляр класса. Чтобы правильно увидеть оба из них, лучше всего делать так, как предлагает Нуфал, и идти dir(), вызывая getattr() для каждого атрибута.

1 голос
/ 03 апреля 2011

Я полагаю, locals() дает вам словарь всех локальных переменных и объектов, на которые они указывают.

Вы также можете попробовать использовать функции eval() или exec() для оценки имен какнеобработанный код Python.Тогда вы можете напрямую использовать результаты из dir().

0 голосов
/ 04 июня 2019

Действительно простой способ перечислить модули:

from <module> import *
print dir(<module>)
0 голосов
/ 03 апреля 2011
class myClass(object):

    def init(self):
        pass


class thing1(myClass):
    def __init__(self):
        self.x = 1

class thing2(myClass):
    def __init__(self):
        self.x = 2

print myClass.__subclasses__()
print vars(thing1())
print vars(thing2())

[<class '__main__.thing1'>, <class '__main__.thing2'>]
{'x': 1}
{'x': 2}
0 голосов
/ 03 апреля 2011

Не уверен, поможет ли это:

class myClass(object):

    def init(self):
        pass


class thing1(myClass):
    def init(self):
        self.x = 1

class thing2(myClass):
    def init(self):
        self.x = 2

myClass.__subclasses__()
[<class '__main__.thing1'>, <class '__main__.thing2'>]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...