Подтвердить что ты не робот

Python: имя класса PEP 8 как переменная

Каково соглашение в соответствии с PEP 8 для записи переменных, которые идентифицируют имена классов (а не экземпляры)?

То есть, учитывая два класса, A и B, какой из следующих утверждений был бы правильным?

target_class = A if some_condition else B
instance = target_class()

или

TargetClass = A if some_condition else B
instance = TargetClass()


Как указано в руководстве по стилю,

Имена классов:

Имена классов обычно должны использовать соглашение CapWords.

Но также

Имена методов и переменные экземпляра:

Используйте правила именования функций: в нижнем регистре со словами, разделенными символами подчеркивания, для повышения удобочитаемости.

По-моему, эти две конвенции сталкиваются, и я не могу найти, какой из них преобладает.

4b9b3361

Ответ 1

Наконец-то я нашел некоторый свет в руководстве :

Имена классов

[...]

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

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

Итак, для общего назначения я считаю, что

target_class = A if some_condition else B
instance = target_class()

лучше, чем

TargetClass = A if some_condition else B
instance = TargetClass()

Ответ 2

При отсутствии конкретного покрытия этого случая в PEP 8 можно составить аргумент для обеих сторон медали:

Одна сторона: Поскольку A и B оба являются переменными, но сохраняйте ссылку на класс, используйте CamelCase (TargetClass) в этом случае.

Ничто не мешает вам делать

class A: pass
class B: pass
x = A
A = B
B = x

Теперь A и B указывают на соответствующий класс, поэтому они действительно не привязаны к классу.

So A и B несут единственную ответственность за сохранение класса (независимо от того, имеют ли они одно и то же имя или другое) и поэтому имеет TargetClass.


Чтобы оставаться беспристрастным, мы также можем спорить по-другому: A и B являются особыми, поскольку они создаются вместе с их классами, а внутренности классов имеют одинаковое имя. Пока они являются "оригинальными", любое другое задание должно быть отмечено специальным, поскольку оно должно рассматриваться как переменная и, следовательно, в lower_case.


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

Пример 1: вы передаете класс, который, возможно, должен быть создан, методу или функции:

def create_new_one(cls):
    return cls()

class A: pass
class B: pass

print(create_new_one(A))

В этом случае cls явно имеет очень временное состояние и, очевидно, переменную; могут быть разными при каждом вызове. Поэтому это должно быть lower_case.

Пример 2: Смещение класса

class OldAPI: pass
class NewAPI: pass
class ThirdAPI: pass
CurrentAPI = ThirdAPI

В этом случае CurrentAPI следует рассматривать как своего рода псевдоним для другого и остается постоянным во время прогона программы. Здесь я бы предпочел CamelCase.

Ответ 3

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

  • Если переменная является временной, например. внутри функции или используется в одном экземпляре при решении проблемы, она должна быть lower_case с подчеркиванием разделения.

  • Если переменная находится в глобальном спектре и определяется вместе с другими классами как псевдоним или деривация, используемые для создания объектов в теле программы, его следует определить с помощью CamelCase.

Ответ 4

В случае сомнений я бы сделал то же самое, что и разработчики Python. Они все-таки писали PEP-8.

Вы можете рассмотреть свою строку:

target_class = A if some_condition else B

в виде строки в виде строки:

target_class = target_class_factory()

и для него есть известный пример в библиотеке Python, namedtuple, который использует CamelCase.