Python Reflection и вызываемые объекты - PullRequest
3 голосов
/ 05 ноября 2010

У меня есть вопрос из двух частей.

>>> class One(object):
...     pass
... 
>>> class Two(object):
...     pass
... 
>>> def digest(constr):
...     c = apply(constr)
...     print c.__class__.__name__
...     print constr.__class__.__name__
... 
>>> digest(Two)
Two
type

Как создать объект «Два»? Ни constr (), ни c () не работают; и кажется, что apply превращает его в тип.

Что происходит, когда вы скорее передаете класс и экземпляр в метод?

Ответы [ 4 ]

5 голосов
/ 05 ноября 2010

Классы являются объектами высокого уровня, поэтому вы можете просто передать их следующим образом:

def createMyClass ( myClass ):
    obj = myClass()
    return obj

class A ( object ):
    pass

>>> x = createMyClass( A )
>>> type( x )
<class '__main__.A'>
1 голос
/ 05 ноября 2010

Как создать объект «Два»?Ни constr (), ни c () не работают;и кажется, что apply преобразует его в тип.

Приведенный выше комментарий был сделан в отношении этого кода:

>>> def digest(constr):
...     c = apply(constr)
...     print c.__class__.__name__
...     print constr.__class__.__name__

apply (устарело: см. ответ @ pyfunc) конечно не превращает класс Two в тип: он уже один.

>>> class Two(object): pass
... 
>>> type(Two)
<type 'type'>

Классы являются объектами первого класса: они являются экземплярами type.Это имеет смысл, если вы посмотрите на следующий пример.

>>> two = Two()
>>> type(two)
<class '__main__.Two'>

Вы можете видеть, что класс очень четко функционирует как тип, потому что он может быть возвращен из type.Вот еще один пример.

>>> Three = type('Three', (Two, ), {'foo': 'bar'})
>>> type(Three)
<type 'type'>
>>> three = Three()
>>> type(three)
<class '__main__.Three'>

Вы можете видеть, что type - это класс, который может быть создан.Его конструктор принимает три аргумента: имя класса, кортеж базовых классов и словарь, содержащий атрибуты класса.Он возвращает новый type aka class.

Что касается вашего последнего вопроса,

Что происходит, когда вы скорее передаете класс и экземпляр в метод?

Тебе нужно быть более конкретным.Классы - это просто экземпляры type и объекты первого класса.Спрашивать, что произойдет, если я передам класс в метод, это все равно, что спросить, что произойдет, если я передам целое число в метод: все зависит от того, что ожидает метод.

1 голос
/ 05 ноября 2010

Просто еще один пример:

def InstanceFactory(classname):
   cls = globals()[classname]
   return cls() 

class A(object):
   def start(self):
       print "a.start"

class B(object):
   def start(self):
        print "b.start"

InstanceFactory("A").start()
InstanceFactory("B").start()

Если класс принадлежит другому модулю:

def InstanceFactory(modulename, classname):
    if '.' in modulename:
        raise ValueError, "can't handle dotted modules yet"
    mod = __import__(modulename)
    cls = getattr(mod, classname]
    return cls() 
0 голосов
/ 05 ноября 2010

Я в замешательстве, хотя.Не применяется () устарело с 2.3

Нам это больше не нужно.

apply(f, args, kwds)  -->  f(*args, **kwds)

У других естьбыл перемещен / считается устаревшим при современном использовании:

  1. buffer ()
  2. coerce ()
  3. и intern ()

Простоиспользуйте: Classname () для создания объекта.

...