2011-07-09 29 views
7

Vengo de Java. Estoy repasando los tutoriales oficiales de Python, pero no puedo encontrar la información en relación con los nombres y las clases de los archivos fuente de Python.Nombre de clase y nombre de archivo

En Java, el nombre del archivo es el mismo que el nombre de la clase principal más la extensión .java. En Python, ¿cuál es el caso? En los ejemplos de tutoriales oficiales, están escribiendo múltiples clases y no se menciona el nombre del archivo. Estoy como perdido.

Tengo un nombre de archivo llamado test_pie.py. El contenido es-

class ListTest: 

    list1 = [2, 'a', 'ab', 'c', 'aa', 0] 

    list2 = ['b', list1[-2:-5]] 

    def PrintList(self): 
     print list1 
     print list2 

Para Lista1 y list2: I Get-

Undefined variable: lista1 lista que se encuentran en: test_pie

Undefined variable: list2 lista que se encuentran en: test_pie

+2

Parece que tiene muchas preguntas aquí. ¿Cuál quieres que responda? –

+0

Puse el fragmento de código porque pensaba que esto se debía a las discrepancias entre nombre de archivo y nombre de clase.Después de editar, vi tu respuesta (fue rápido). Me gustó tu respuesta. Esto fue claro. –

+0

El fragmento de código no tiene nada que ver con ninguna de las preguntas anteriores. –

Respuesta

7

Hay un archivo. Período. Lo que está contenido en él no interesa a las importaciones, y el nombre o ubicación del archivo no tiene ningún efecto sobre el código contenido (generalmente, es accesible durante la ejecución, por lo que algunas metaprogramaciones lo usan pero deben ser agnósticas wrt el valor real).

El contenido de un archivo es no restringido a una sola clase, y pocas personas se imponen tal restricción sobre sí mismos. Python no es exclusivamente un lenguaje OO, puede y debe tener funciones gratuitas siempre que sea sensato, y los módulos se ven un nivel por encima de las clases en las organizaciones de códigos: si varias clases están estrechamente relacionadas, deberían incluirse en un módulo.

Su problema/código de ejemplo no está relacionado con esto, es una cuestión de alcance dentro de un archivo determinado. Las clases tienen su propio alcance, pero no se pueden usar ni se deben usar las variables de clase de la clase contenedora en métodos como este (directamente); esto haría que el código no tenga en cuenta un nuevo valor establecido en una subclase. En su lugar, o bien utiliza métodos de clase (por cierto, debe leer http://dirtsimple.org/2004/12/python-is-not-java.html) o hacer uso del hecho de que las instancias heredan todos los miembros de la clase y simplemente lo anteponen con self..

+0

Esto es muy claro. Gracias por tu tiempo. Lo aprecio. –

+1

Las instancias no "heredan" atributos (el nombre Pythonic para "miembros") de la clase; más bien, intentar buscar un atributo en un objeto también intentará buscar en la clase si el objeto no tiene uno. Esto significa que si 'list1' se usa de esta manera, se ** compartirá ** efectivamente entre las instancias de la clase. Tener cuidado. –

+0

@Karl: Sí, eso es lo que quise decir pero no expresé correctamente. Gracias por la aclaración. – delnan

8

En Python, un solo archivo constituye un módulo, que es similar a un espacio de nombres en Java, por lo que tendría todas las clases para un solo espacio de nombres en el s ame archivo

2

Java no es Python. Python no es Java. Hay muchas diferencias que acaba de descubrir aquí; más de lo que esperarías

En Java, el nombre del archivo es el mismo que el nombre de la clase principal más la extensión .java. En Python, ¿cuál es el caso?

Lo opuesto: el nombre del archivo no es necesariamente el mismo que cualquier otro.

En los ejemplos de tutoriales oficiales, escriben varias clases y no se menciona el nombre del archivo. Estoy como perdido.

Porque no importa. (Tenga en cuenta que en Java todavía puede tener más de una clase por archivo, siempre que solo una, con el nombre correspondiente, sea public.En Python, public en realidad no existe como tal)

Para Lista1 y lista2:. I Get-

Undefined variable: lista lista1 encontrar en: test_pie

Undefined variable: Lista lista2 encontrados at: test_pie

Esto se debe a que esos atributos (lo que llamarían "campos" en Java) pertenecen a la clase, no al objeto.

El método (el mismo nombre que Java) todavía "pertenece" a la clase, en Python-think, pero se accede a través de un objeto. Es por eso que necesita un parámetro self explícito para los métodos de Python: porque my_object.do_something(x, y, z) se traduce implícitamente a MyClass.do_something(my_object, x, y, z) (más o menos; hay algunos engaños detrás de las escenas con "vinculante", que le permite tratar my_object.do_something como un objeto. Sí, en Python , todo es un objeto, incluso funciones. Y pensabas que Java era OO. Hah.)

Todavía puedes acceder a los atributos de clase a través de un objeto, si le dices a Python dónde buscarlo. Dentro de PrintList, list1 y list2 están no en alcance, porque Python realmente solo tiene dos ámbitos: local y global. Pero self está dentro del alcance (es un parámetro, por lo que está en el ámbito local), y puede acceder al self.list1, ya que buscar un atributo en un objeto en Python recae en los atributos de clase si no hay un atributo de objeto. (En realidad, es más complicado que eso, hay un par de ganchos diferentes de nombre de método especial que puede insertar en el proceso, por no mencionar cómo se trata la herencia).

Así que probablemente se esté preguntando por ahora cómo se obtienen atributos en un objeto real de Python en lugar de su clase. La respuesta: simplemente los asignas. Si no coloca ninguna restricción, puede asignarlas en cualquier momento, con cualquier nombre. El objeto es básicamente solo un diccionario. Si está familiarizado con Java * secuencia de comandos * (un lenguaje completamente ajeno a Java), entonces funciona de la misma manera. Sin embargo, para controlar la locura, es normal asignar valores iniciales de atributo en un método especialmente nombrado __init__, que se llama automáticamente (si se encuentra) inmediatamente después de la creación del objeto (pero es no un constructor en el habitual sentido, ese rol lo juega __new__, pero casi nunca lo necesitas en Python), y luego solo reasignas los atributos que se establecieron allí en lugar de crear nuevos.

Puede establecer restricciones, si tiene una clase de estilo nuevo (automática en 3.x; en 2.x debe heredar al menos indirectamente del tipo integrado object), especificando un valor para un valor el atributo de clase con nombre llamado __slots__. Esta debería ser una lista de cadenas que son nombres de identificadores válidos. Con esto en su lugar, Python (a) usará la información para optimizar su almacenamiento interno de datos para los objetos; (b) no le permite agregar atributos con otros nombres al objeto; (c) suprimir la creación del atributo especial __dict__ para instancias de objeto que es un nombre de atributo de asignación de diccionario a valores de atributo. (Y pensaste que Java soportaba la reflexión. Hah.) no asigna automáticamente cualquier valor para los atributos nombrados; intentar acceder a ellos antes de que se les haya asignado será raise AttributeError.

Cuestiones relacionadas