name - Python: nombre de clase PEP 8 como variable
python 3 naming conventions (4)
¿Cuál es la convención según PEP 8 para escribir variables que identifican nombres de clase (no instancias)?
Es decir, dadas dos clases, A
y B
, ¿cuál de las siguientes afirmaciones sería la correcta?
target_class = A if some_condition else B
instance = target_class()
o
TargetClass = A if some_condition else B
instance = TargetClass()
Como se indica en la guía de estilo,
Nombres de clase :
Los nombres de clase normalmente deben usar la convención de CapWords.
Pero también
Nombres de métodos y variables de instancia:
Utilice las reglas de nomenclatura de funciones: minúsculas con palabras separadas por guiones bajos según sea necesario para mejorar la legibilidad.
En mi opinión, estas dos convenciones chocan y no encuentro cuál prevalece.
A falta de una cobertura específica de este caso en PEP 8, uno puede inventar un argumento para ambos lados de la medalla:
Un lado es: como A
y B
también son variables, pero mantenga una referencia a una clase, use CamelCase ( TargetClass
) en este caso.
Nada te impide hacer
class A: pass
class B: pass
x = A
A = B
B = x
Ahora, A
y B
apuntan a la otra clase respectivamente, por lo que no están realmente fijas a la clase.
Por lo tanto, A
y B
tienen la única responsabilidad de mantener una clase (sin importar si tienen el mismo nombre o uno diferente), y también TargetClass
.
Para mantenernos imparciales, también podemos argumentar de otra manera: A
y B
son especiales en la medida en que se crean junto con sus clases, y las partes internas de las clases tienen el mismo nombre. En la medida en que son una especie de "original", cualquier otra asignación debe marcarse como especial en la medida en que deben verse como una variable y, por lo tanto, en la lower_case
.
La verdad está, como muy a menudo, en algún lugar en el medio. Hay casos en los que yo iría por un lado y otros por el otro.
Ejemplo 1: Pasas una clase, que tal vez debería ser instanciada, a un método o función:
def create_new_one(cls):
return cls()
class A: pass
class B: pass
print(create_new_one(A))
En este caso, cls
es claramente de estado muy temporal y claramente una variable; Puede ser diferente en cada llamada. Por lo tanto, debería ser lower_case
.
Ejemplo 2: Alias de una clase
class OldAPI: pass
class NewAPI: pass
class ThirdAPI: pass
CurrentAPI = ThirdAPI
En este caso, CurrentAPI
debe verse como un tipo de alias para el otro y permanece constante durante la ejecución del programa. Aquí preferiría CamelCase
.
En caso de duda, haría lo mismo que los desarrolladores de Python. Escribieron el PEP-8 después de todo.
Puedes considerar tu línea:
target_class = A if some_condition else B
como una forma en línea del patrón:
target_class = target_class_factory()
y hay un ejemplo bien conocido para ello en la biblioteca de Python, namedtuple , que usa CamelCase.
Finalmente encontré algo de luz en la guía de estilo :
Nombres de clase
[...]
La convención de nomenclatura para las funciones se puede usar en lugar de eso, en los casos en que la interfaz se documenta y se usa principalmente como un llamador.
puede ser usado no es una afirmación fuerte, pero cubre el caso, ya que la variable fue pensada para usarse como un llamador.
Así que, para fines generales creo que
target_class = A if some_condition else B
instance = target_class()
es mejor que
TargetClass = A if some_condition else B
instance = TargetClass()
Personalmente creo que si la variable que mencionó, que contiene una referencia a una clase, se define como una variable temporal (por ejemplo, en un procedimiento o función) o como una derivación de una clase existente en el espectro global tiene el mayor peso en El caso de cuál usar. Así que para resumir de la respuesta anterior:
Si la variable es temporal, por ejemplo, dentro de una función o utilizada en una sola instancia en la resolución de un problema, debe ser
lower_case
con una separación de subrayado.Si la variable está dentro del espectro global, y se define junto con las otras clases como un alias o derivación que se usará para crear objetos en el cuerpo del programa, se debe definir utilizando
CamelCase
.