Какой код выполняется при определении класса?

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


Изменить: я понимаю, что мой вопрос может быть слишком общим ...

Я ищу что-то более низкоуровневое, что позволит мне заниматься самоанализом с C ++. Я расширяю свое приложение на C ++ с помощью Python. У меня есть несколько классов, которые определены в C ++ и представлены в Python. Пользователь может наследовать эти классы в сценариях, и я хочу иметь возможность получать подробную информацию о них, когда они будут определены впервые.


person Paul Manta    schedule 29.10.2011    source источник
comment
Какой код выполняется для фактического создания класса, зависит от того, является ли он классом старого или нового стиля - у вас есть предпочтительная версия Python?   -  person Thomas    schedule 30.10.2011
comment
@Thomas Тогда пусть будет Python 3.   -  person Paul Manta    schedule 30.10.2011


Ответы (5)


Может случиться много всего. Самый простой:

Содержимое блока class выполняется при первом чтении.

Чтобы увидеть это в действии, рассмотрим следующий пример:

class Foo(object):
    print "bar"

    def __init__(self):
        print "baz"

Будет печатать bar при импорте модуля.

Если для класса определен метакласс, функция метаклассов __new__ будет запущена после запуска блока кода классов.

Пример:

class MyMeta(type):
    def __new__(mcs, name, bases, kwargs):
        print "I'm the metaclass, just checking in."
        return type.__new__(mcs, name, bases, kwargs)


class Foo(object):
    __metaclass__ = MyMeta

    print "I'm the Foo class"

Выход:

I'm the Foo class
I'm the metaclass, just checking in.

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

person Adam Wagner    schedule 29.10.2011
comment
Я думаю, что вопрос заключается в деталях объекта Python с точки зрения C ++ .... Я думаю. Очевидно, мой ответ не касается этого, однако это было до того, как вопрос был отредактирован, чтобы более четко указать на это намерение. - person Adam Wagner; 30.10.2011

При определении класса A, который наследуется от B и C, выполняется: A = type('A', (B, C), m где m - словарь, содержащий члены класса.

Вы можете влиять на процесс, используя программирование метаклассов. Нет недостатка в сообщениях в блогах. и учебные пособия по этой теме.

person Raymond Hettinger    schedule 29.10.2011

Возможно, вас заинтересуют метаклассы, которые управляют создание классов.

person Colin Valliant    schedule 29.10.2011

Код в определении класса выполняется так же, как и любой другой код, но любые созданные переменные (включая определения функций) будут находиться в контексте класса, а не глобально. Это означает, что вы можете динамически изменять определение класса, добавляя условный код:

class A(object):
    if 1==2:
        def f(self):
            print "the world has gone mad"
    else:
        def f(self):
            print "sanity rules"

>>> a = A()
>>> a.f()
sanity rules
>>> 

Однако я никогда не видел, чтобы это было сделано, и не могу придумать причину, по которой это делается - это кажется довольно непифоничным.

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

person Dave Kirby    schedule 29.10.2011

Python интерпретируется, поэтому, когда модуль Python импортируется, запускается любой код класса на уровне модуля вместе с метаклассами этих классов - это значит, что классы будут существовать.

C ++ скомпилирован: классы уже существуют на момент импорта; нет возможности контролировать, как они создаются, поскольку они уже созданы.

person Ethan Furman    schedule 30.10.2011