Как получить переменные экземпляра в Python? - PullRequest
99 голосов
/ 20 сентября 2008

Есть ли в Python встроенный метод для получения массива всех переменных экземпляра класса? Например, если у меня есть этот код:

class hi:
  def __init__(self):
    self.ii = "foo"
    self.kk = "bar"

Есть ли для меня способ сделать это:

>>> mystery_method(hi)
["ii", "kk"]

Редактировать: Первоначально я ошибочно попросил переменные класса.

Ответы [ 8 ]

119 голосов
/ 20 сентября 2008

Каждый объект имеет переменную __dict__, содержащую все переменные и их значения.

Попробуйте это

>>> hi_obj = hi()
>>> hi_obj.__dict__.keys()
86 голосов
/ 21 сентября 2008

Использовать переменные ()

class Foo(object):
    def __init__(self):
        self.a = 1
        self.b = 2

vars(Foo()) #==> {'a': 1, 'b': 2}
vars(Foo()).keys() #==> ['a', 'b']
13 голосов
/ 24 декабря 2010

Оба метода Vars () и dict будут работать для примера, опубликованного ОП, но они не будут работать для "свободно" определенных объектов, таких как:

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
13 голосов
/ 20 сентября 2008

Обычно вы не можете получить атрибуты экземпляра, заданные только классом, по крайней мере, без создания экземпляра класса. Вы можете получить атрибуты экземпляра для данного экземпляра или атрибуты класса для данного класса. Смотрите модуль «осмотр». Вы не можете получить список атрибутов экземпляра, потому что экземпляры действительно могут иметь что-либо в качестве атрибута, и - как в вашем примере - обычный способ их создания - просто присвоить им метод __init__.

Исключение составляют случаи, когда ваш класс использует слоты, представляющие собой фиксированный список атрибутов, которые класс может иметь для экземпляров. Слоты объясняются в http://www.python.org/2.2.3/descrintro.html,, но есть различные ловушки со слотами; они влияют на структуру памяти, поэтому множественное наследование может быть проблематичным, и наследование в целом также должно учитывать слоты.

10 голосов
/ 20 сентября 2008

Вы также можете проверить, имеет ли объект конкретную переменную с помощью:

>>> hi_obj = hi()
>>> hasattr(hi_obj, "some attribute")
6 голосов
/ 21 сентября 2008

Предлагайте

>>> print vars.__doc__
vars([object]) -> dictionary

Without arguments, equivalent to locals().
With an argument, equivalent to object.__dict__.

Другими словами, это просто обертка __dict__

5 голосов
/ 21 сентября 2008

Хотя это и не прямой ответ на вопрос 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'
5 голосов
/ 20 сентября 2008

В вашем примере показаны "переменные экземпляра", а не переменные класса.

Найдите в 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"

Переменные класса являются общими для всех экземпляров класса.

...