Как закрытия класса Python работают?

Если я делаю класс против локального пространства имен, как точно это работает? Например:

>>> def foo():
...     i = 1
...     class bar(object):
...             j = i
...     return bar
... 
>>> dis(foo)
  2           0 LOAD_CONST               1 (1)
              3 STORE_DEREF              0 (i)

  3           6 LOAD_CONST               2 ('bar')
              9 LOAD_GLOBAL              0 (object)
             12 BUILD_TUPLE              1
             15 LOAD_CLOSURE             0 (i)
             18 BUILD_TUPLE              1
             21 LOAD_CONST               3 (<code object bar at 0xb74f8800, file "<stdin>", line 3>)
             24 MAKE_CLOSURE             0
             27 CALL_FUNCTION            0
             30 BUILD_CLASS         
             31 STORE_FAST               0 (bar)

  5          34 LOAD_FAST                0 (bar)
             37 RETURN_VALUE        

Конкретные строки, на предмет которых мне любопытно, являются ими:

             15 LOAD_CLOSURE             0 (i)
             18 BUILD_TUPLE              1
             21 LOAD_CONST               3 (<code object bar at 0xb74f8800, file "<stdin>", line 3>)
             24 MAKE_CLOSURE             0
             27 CALL_FUNCTION            0
             30 BUILD_CLASS

Я предполагаю самую большую вещь, что я задаюсь вопросом, то, какая функция делается и затем вызывается? И состоит в том эта функция, где закрытия присоединены к классу, или это происходит в другом месте?

6
задан Jason Baker 3 February 2010 в 14:59
поделиться

1 ответ

Одним из основных рисков является смещение байтов. Символ со знаком сохраняет бит знака при смещении вправо, а символ без знака - нет. Вот небольшая тестовая программа:

#include <stdio.h>

int main (void)
{
    signed char a = -1;
    unsigned char b = 255;

    printf("%d\n%d\n", a >> 1, b >> 1);

    return 0;
}

Она должна печатать -1 и 127, несмотря на то, что a и b начинаются с одного и того же бита образца (учитывая 8-битовые символы, два комплементарных и знаковых значения с помощью арифметического сдвига).

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

-121--2858839-

Часто ли изменяются все 100 000 записей? Или это подмножество, которое изменяется?

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

-121--1679970-

Все тело класса, т.е.

j = i

, является объектом кода, который загружается при смещении 21, а затем вызывается при смещении 27 с помощью CALL _ FUNCTION . Результат вызова (локальное пространство имен) затем используется вместе с именем класса и базами данных для создания класса. BUILD _ CLASS принимает три аргумента, аналогично функции type (имя, базы, dict) :

Возвращает новый объект типа. По существу, это динамическая форма оператора класса. Имя последовательности является именем класса и становится атрибутом name ; базовый кортеж детализирует базовые классы и становится атрибутом bases ; и dict-словарь является пространством имен, содержащим определения для тела класса, и становится атрибутом dict .

Есть также очень подробная статья «Примечания к утверждению класса Python» , объясняющая, как работает создание класса.

2
ответ дан 17 December 2019 в 20:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: