¿Cómo debo nombrar las funciones que devuelven valores en Python?

13

Estoy confundido acerca de elegir nombres para mis funciones en Python . A veces , las funciones integradas de Python son imprescindibles, tales como: printfunción y método de cadena find. A veces no son tales como: lensu nombre no es imprescindible como calculate_len, por ejemplo, y typeno lo es find_type.

Puedo entender que printdevuelve 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 lendevuelve 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 findmé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_letterlugar de rotated_letter.

rotated_letterdevuelve una cadena de una letra que representa una letra girada por un número. No sé qué es mejor, lo usé, rotated_letterya que devuelve un valor, como la randintfunció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_eveny is_palindromesimplemente lo hacemos como una pregunta de sí / no , y también funciones que solo hacen y devuelven valores no utilizados (es decir None, como printmétodo de lista sort.

Mahmood Muhammad Nageeb
fuente
esa es en realidad una práctica muy común (yo diría una convención) usar imperativos al nombrar la función. Por ejemplo, ¿cómo nombra una variable que almacena la letra rotada de la función rotated_letter?
JoulinRouge
Esa no es una buena manera de pensar en algunos de sus ejemplos. len, por ejemplo, se considera mejor como "longitud de": está obteniendo una descripción de nivel meta de su argumento.
Izkata

Respuestas:

10

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)vs list(foo).: El sustantivo es más fácil de leer que el verbo. Además, en listrealidad es una clase, y las clases deben ser sustantivos.
  • open(foo)vs file(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(asume fooy barson ambos sustantivos): la primera opción es inmediata, porque el "get" no agrega nada que no supiéramos. El segundo es apropiado si barsalir de una foooperación potencialmente costosa y / o conlleva efectos secundarios (también puede considerar Bar(foo)si Bares 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)si xses 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 iomó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.

Kevin
fuente
¡Gracias! En " foo.get_bar() vs.` foo.bar ()` vs. foo.bar" ¿cuál es la diferencia entre el segundo y el tercero ?
Mahmood Muhammad Nageeb
El tercero es una propiedad o un atributo simple. El segundo es un método.
Kevin
Entonces, si entiendo, es apropiado no hacer rotated_letterimperativo y mantenerlo declarativo, ¿verdad?
Mahmood Muhammad Nageeb
En este caso, no estoy seguro de si letterestá implícito en el contexto.
Kevin
+1 por mencionar listes una clase
Dušan Maďar
0

rotated_letterno parece un método Parece una propiedad. Lo que significa que la primera idea es hacer:

var letter = caesar.rotated_letter

esperando lettercontener un valor de tipo cadena, no una función. A partir de ahí, puede elegir un nombre diferente, como:

def rotate_letter(self):
    pass

o usas una propiedad en su lugar:

@property
def rotated_letter(self):
    return self.whatever

leny typese 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 como length(a menos que la forma abreviada sea muy popular, como max), y use un verbo como compute_length. O podría ser una propiedad: se len([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 #, preferidos Count, que generalmente es un método (aunque desafortunadamente el comportamiento es inconsistente a través de .NET Framework). Countes 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 en product.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 como value++.

  • 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.

Arseni Mourzenko
fuente
Supongo que la respuesta es "sí", pero debo preguntar: ¿está respondiendo completamente desde la perspectiva de Python? Porque en otros idiomas su separación de función vs propiedad no siempre es verdadera; Tampoco es cierto que una función "debe realizar una acción". ¿Es esta la convención en Python? (Escribo Python pero no he leído todas las PEP y definitivamente NO soy un experto. No voté en contra, BTW).
Andres F.
@AndresF .: estoy respondiendo desde la perspectiva de Python. En lenguajes como Java, donde las propiedades no existen getSomethingy setSomethingson los nombres habituales utilizados en lugar de las propiedades.
Arseni Mourzenko