Recibí la respuesta de Michael Kent por segunda vez (y la volví a subir).
Pero también, debe leer "PEP 8" y absorber sus lecciones.
http://www.python.org/dev/peps/pep-0008/
Pero Python, con sus espacios de nombres, características de gran alcance, y las clases orientadas a objetos, se debe dejar que se utiliza convenientemente nombres cortos para las cosas.
En C, necesita utilizar identificadores largos en muchos casos porque los nombres deben ser únicos dentro de un ámbito determinado. Por lo tanto:
char *StringFromInt(int x);
char *StringFromFloat(float x);
char *StringFromUnsigned(unsigned int x);
char *str_temp = strdup(StringFromUnsigned(foo_flags));
En Python, todos estos serían la orden interna str()
:
temp = str(foo_flags)
En C++ tiene clases y espacios de nombres, por lo que debe ser capaz de utilizar las funciones orientadas a objetos como en Python, pero en C necesita nombres únicos a nivel mundial, por lo que a menudo tienen que hacer cosas como esta:
typedef struct s_foo
{
// struct members go here
} FOO;
FooAdd();
FooSubtract();
StringFromFoo();
en Python, debe o bien agregar funciones miembro u operadores de sobrecarga, según el caso:
class Foo(object):
def __init__(self):
# member variables initialized here
def add(self, x):
# add x to a Foo
def subtract(self, x):
# subtract x from a Foo
def __str___(self):
# return a string that represents a foo
f = Foo()
f.add(x)
f.sub(y)
# the following two both use __str__()
temp = str(f)
print(f)
También puede preferir nombres de variables realmente largos para fines de auto-documentación. Prefiero concisión:
import math
class Circle(object):
"""\
Circle: a class representing a circle in a plane.
Includes the following member functions:
area() -- return the area of the circle"""
def __init__(self, center=Point([0, 0]), radius=0.0):
"""\
Circle(center, radius)
center must be an instance of class Point() or convertible to Point()
radius must be an int or float and must not be negative"""
if radius < 0:
raise ValueError("radius must be >= 0")
self.center = Point(center)
self.radius = float(radius)
def area(self):
"returns area as a float."
return math.pi * self.radius ** 2
c = Circle([23, 45], 0.5)
print(c.area())
class CircleGraphicsObject(object):
def __init__(self, CenterOfTheCircle, RadiusOfTheCircle):
# init code goes here
def AreaOfTheCircle(self):
return math.pi * self.RadiusOfTheCircle ** 2
CircleInstance = CircleGraphicsObject(PointObject([23, 45]), 0.5)
print(CircleInstance.AreaOfTheCircle())
Yo prefiero el primer estilo rápido al segundo. Según PEP 8, me gustan los nombres de variables en minúsculas (como c
para la instancia Circle
). En Python, también se recomienda generalmente usar "Duck Typing" como hice en la clase terse: si quieres que el radio sea un flotante, entonces coacciona a float
en __init__()
en lugar de verificar su tipo. Del mismo modo, en lugar de verificar si se aprobó una instancia de Point
, simplemente fuerce lo que obtenga a Point
.Está dejando que Point.__init__()
presente una excepción si el argumento no tiene sentido como Point
; no hay necesidad de un cheque adicional en Circle.__init__()
. Además, su función Point.__init__()
puede verificar explícitamente para ver si le pasó una instancia de Point
y devolver la instancia sin cambios, si es realmente costoso iniciar un Point
. (En este ejemplo, un Point
es realmente solo un par de valores, por lo que probablemente sea lo suficientemente rápido para volver a crear el punto y no necesita el cheque.)
Puede notar la forma extraña en que hice el cadena multi-línea de citas triples Debido a las reglas de sangrado en Python, necesité sangrar la cadena de comillas triples, pero no quiero aplicar sangría a las líneas de la cadena porque la sangría sería parte de la cadena. Realmente quiero que todas las líneas múltiples estén en el margen izquierdo, así puedo ver claramente cuánto tiempo están obteniendo esas líneas (y me aseguro de que sean todas 79 caracteres o más cortas). Así que utilizo el escape de barra invertida para permitir que la primera línea de la cadena de varias líneas esté en el margen izquierdo con las otras líneas, sin insertar una línea nueva al comienzo de la cadena de varias líneas.
De todos modos, el estilo más concisa significa que los nombres de las variables y tales son más fáciles de escribir, y es más fácil para adaptarse a sus líneas en el límite de 79 columnas recomendadas por PEP 8.
Ni siquiera sería completamente Es horrible usar nombres de miembros internos que tienen una sola letra, en una clase tan simple como esta. Con solo dos miembros, puede usar .c
para el miembro central y .r
para el radio. Pero eso no se escala bien, y .center
y .radius
son fáciles de escribir y fáciles de recordar.
También es una muy buena idea poner docstrings informativos. Puede usar nombres algo escuetos, pero tener explicaciones más largas en la docstring.
class Foo(object):
# init goes here
def area(self):
"returns area as a float."
return self.area
class VerboseFoo(object):
# init goes here
def AreaAsFloat(self):
return self.FloatAreaValue
Los espacios de nombres son geniales. Observe qué tan claro es cuando usamos math.pi
; usted sabe que es la constante matemática, y podría tener alguna variable local pi
(para el "Índice del programa") y no colisiona con la constante matemática.
Uno de los problemas puede ser el hecho de que sus nombres son tan largos. Trata de pensar en formas más cortas de describir las cosas. – Amber
Creo que mis nombres realmente terminan por las variables de clase. Si estoy llamando a una función con tres variables de clase, solo el "yo". una porción de esos nombres variables ya mata 15 caracteres. En términos de reducción de nombre en general, estoy realmente en contra de cambiar un nombre a algo ininteligible solo para ahorrar espacio. Un nombre debe ser tan pequeño como sea posible sin dejar de describir razonablemente qué es. – Eli
Subida al contador como desventaja de @Glenn Maynard. PEP 8 establece claramente, "Limitar todas las líneas a un máximo de 79 caracteres". – Johnsyweb