Estoy confundido acerca de elegir nombres para mis funciones en Python . A veces , las funciones integradas de Python son imprescindibles, tales como: print
función y método de cadena find
. A veces no son tales como: len
su nombre no es imprescindible como calculate_len
, por ejemplo, y type
no lo es find_type
.
Puedo entender que print
devuelve un valor que no usamos (es decir None
) y hace algo (es decir, muestra una cadena en la pantalla), por lo que su nombre es imprescindible.
Pero len
devuelve un valor que usamos y hace algo (es decir, calcular cuántos elementos hay en una secuencia o un mapeo) y su nombre no es imprescindible . Por otro lado, el find
método de cadena (as len
) devuelve un valor que usamos y hace algo, y su nombre es imperativo .
Lo que hizo esta pregunta es que puse un script que encripta y desencripta la cadena usando el cifrado Caesar para su revisión. El revisor dijo que:
Solo un presentimiento: las funciones hacen cosas. Por lo tanto, un buen nombre para una función es un imperativo: usaría en
rotate_letter
lugar derotated_letter
.
rotated_letter
devuelve una cadena de una letra que representa una letra girada por un número. No sé qué es mejor, lo usé, rotated_letter
ya que devuelve un valor, como la randint
función en el módulo aleatorio , no lo es generate_randint
.
Entonces, en este caso, ¿cómo debo nombrar una función que devuelve un valor para ser utilizado? ¿Debo hacer que el nombre sea imperativo o simplemente un sustantivo ? En otros casos, es obvio cómo hacerlo, como funciones booleanas , como is_even
y is_palindrome
simplemente lo hacemos como una pregunta de sí / no , y también funciones que solo hacen y devuelven valores no utilizados (es decir None
, como print
método de lista sort
.
fuente
len
, por ejemplo, se considera mejor como "longitud de": está obteniendo una descripción de nivel meta de su argumento.Respuestas:
Use verbos donde sean razonables, sustantivos si son más cortos e inequívocos
La mayoría de las veces, las funciones deben ser verbos (imperativos) y las clases, las variables y los parámetros deben ser sustantivos. Los atributos también deben ser sustantivos, incluidos los creados con
@property
. Este es especialmente el caso de las funciones que tienen efectos secundarios. [1] Si una función devuelve algo, debe evaluar si el verbo agrega algo o es solo "ruido":make_list(foo)
vslist(foo)
.: El sustantivo es más fácil de leer que el verbo. Además, enlist
realidad es una clase, y las clases deben ser sustantivos.open(foo)
vsfile(foo)
.: El verbo es más fácil de leer que el sustantivo, y tiene más sentido dar "opciones" a un verbo que a un sustantivo, por lo que el sustantivo se eliminó en Python 3.open()
sigue siendo la única forma "estándar" [2] para crear objetos de archivo en Python 3.foo.get_bar()
vs.foo.bar()
vs.foo.bar
(asumefoo
ybar
son ambos sustantivos): la primera opción es inmediata, porque el "get" no agrega nada que no supiéramos. El segundo es apropiado sibar
salir de unafoo
operación potencialmente costosa y / o conlleva efectos secundarios (también puede considerarBar(foo)
siBar
es una clase). El tercero es apropiado si se trata de una operación barata sin efectos secundarios, y es poco probable que las implementaciones alternativas lo hagan costoso .xs.sort()
vs.sorted(xs)
sixs
es una lista: la primera es imprescindible: ordenar la lista. Modifica la lista en el lugar y no devuelve nada. El segundo es declarativo: una lista ordenada, que es precisamente lo que devuelve. Ambos son verbos.[1]: Por lo general, devolver un valor y tener efectos secundarios son mutuamente excluyentes a menos que tenga alguna razón de diseño convincente para combinarlos. Entonces, una función que tiene efectos secundarios probablemente no debería devolver nada y, por lo tanto, convertirla en un sustantivo tendría muy poco sentido.
[2]: Hay algunas operaciones de nivel moderadamente inferior en el
io
módulo que se pueden usar para agregar o eliminar el almacenamiento en búfer de archivos, el texto automático en / decodificación, etc., y estos son principalmente sustantivos porque son clases orientadas a objetos. La mayoría de los usuarios no necesitan jugar con estas cosas directamente; en su lugar,open()
elige una clase apropiada y la instancia automáticamente.fuente
foo.get_bar()
vs.` foo.bar ()` vs.foo.bar
" ¿cuál es la diferencia entre el segundo y el tercero ?rotated_letter
imperativo y mantenerlo declarativo, ¿verdad?letter
está implícito en el contexto.list
es una claserotated_letter
no parece un método Parece una propiedad. Lo que significa que la primera idea es hacer:esperando
letter
contener un valor de tipo cadena, no una función. A partir de ahí, puede elegir un nombre diferente, como:o usas una propiedad en su lugar:
len
ytype
se nombran así porque cualquier otro nombre sería largo de escribir. Se usan mucho y tienen un estado especial de las funciones centrales de Python que todo programador de Python aprenderá de todos modos, lo que hace que sus nombres sean mucho más irrelevantes que los nombres de bibliotecas de terceros.len
, especialmente, es un buen ejemplo de lo que no debe hacer en su código: se espera que use nombres completos comolength
(a menos que la forma abreviada sea muy popular, comomax
), y use un verbo comocompute_length
. O podría ser una propiedad: selen([1, 5, 6])
convierte[1, 5, 6].length
. Por ejemplo, en C #, se utiliza la forma más tarde:new [] { ... }.Length
.Tenga en cuenta que también puede haber razones históricas para
len
: otros lenguajes, como C #, preferidosCount
, que generalmente es un método (aunque desafortunadamente el comportamiento es inconsistente a través de .NET Framework).Count
es un verbo, así que intuitivamente, estás inclinado a invocarlo como método.Devolver valores o realizar una acción
Siempre se espera que una función realice una acción. Si apenas devuelve un valor, debería ser una propiedad. Tiene una pista de que la función debe transformarse en una propiedad cuando:
La función apenas contiene una
return ...
declaración,El nombre de la función que viene naturalmente a su mente es
get_something
, como enproduct.get_price()
.Ahora, si tiene una función, puede ser uno de cuatro tipos:
Puede ser puro, es decir, devolver un valor sin afectar el medio ambiente. Ejemplo:
road.measure_distance()
.Puede afectar el medio ambiente sin devolver nada. Ejemplo:
product_database.remove_record(1234)
.Puede afectar el medio ambiente y devolver un valor. Ejemplo:
value.increment()
usado comovalue++
.No puede hacer nada y no devolver nada. Ejemplo:
time.sleep(1)
.Hay pocos casos en los que el nombre podría dar una pista clara sobre el tipo de función, pero en muchos casos, no podrá saber el tipo apenas por su nombre.
fuente
getSomething
ysetSomething
son los nombres habituales utilizados en lugar de las propiedades.