Python es un lenguaje de programación de alto nivel orientado a objetos. En Python, "todo es un objeto": los tipos de datos incorporados como números, cadenas, tuplas, listas, diccionarios, colecciones y funciones, métodos, clases y módulos son todos objetos.
El lenguaje en sí proporciona los objetos básicos mencionados anteriormente, pero en la programación real, tenemos que crear una variedad de objetos, y Python nos proporciona una manera de crear nuestros propios objetos: clases .
La clase es una forma de combinar datos y funcionalidad. Nos permite crear un nuevo tipo de objeto y crear una nueva instancia de ese tipo. Los datos de una combinación de clases son la propiedad que posee su propio estado, y la función (función) que combina es el método que cambia su estado (definido en la clase). Una función definida dentro de una clase, llamada método de una clase.
Las clases en Python tienen muchas características similares a otros lenguajes (como C ++) pero hay algunas diferencias. Si ya conoce los conceptos de clases en otros idiomas, puede hacer una comparación al aprender las clases de Python; si no ha aprendido otros idiomas, no importa. Después de aprender, encontrará que el concepto de clases es muy simple.
Definición de clase
La definición de la class implementa mediante la class palabra clave. Esta es la definición de la clase más simple:
class ClassName:
Declaración 1
...
Declaración n
Es esta forma muy similar a la definición de una función (declaración def). Debido a que una clase es una combinación de datos y funciones, la Declaración 1 puede ser una definición de una variable interna (datos) y una declaración de asignación, o puede ser una definición de un método interno (función). Una definición de función dentro de una clase generalmente tiene una forma especial de lista de parámetros, que se especifica en la especificación de la convención de la llamada al método. Esta forma especial es que el primer parámetro debe ser self , que se describirá en detalle más adelante.
Cuando ingresa la definición de clase, se crea un nuevo espacio de nombres y se usa como un ámbito local. Por lo tanto, todas las asignaciones a variables locales se realizan dentro de este nuevo espacio de nombres. En particular, la definición de la función está vinculada al nuevo nombre de la función en este ámbito local.
Un objeto de clase se crea cuando la definición de clase normalmente se deja (desde el final). Básicamente es un contenedor alrededor del contenido del espacio de nombres creado por la definición de clase. El alcance local del elemento (que actúa antes de ingresar la definición de clase) se volverá a validar, y el objeto de clase se vinculará aquí al nombre de clase dado por el encabezado de definición de clase ( ClassName en el ejemplo anterior).
Objeto de clase
Los objetos de clase (como el ClassName ejemplo anterior) admiten dos operaciones: referencia de propiedad y creación de instancias .
La sintaxis de una referencia de propiedad es la misma que la de todas las propiedades en Python: obj.name . Todos los nombres que existen en el espacio de nombres de clase cuando se crea el objeto de clase son nombres de propiedad válidos. Aquí hay una definición de clase simple que contiene datos y métodos:
class YuanRenXue:
"""A demo of class"""
name = 'learnpython'
def say_hi(self):
print('Hello world!')
Las referencias de atributo válidas a esta clase son: YuanRenXue.name y YuanRenXue.say_hi , que devuelven una cadena y un objeto de función, respectivamente.
Los atributos de clase también pueden asignarse, por lo que puede cambiar el valor de Yuanrenxue.name asignando un valor.
El __doc__ de la clase también es una propiedad válida, y una referencia a la misma devuelve la 'A demo of class' pertenece: 'A demo of class' .
La creación de instancias de una clase es una notación de función que trata un objeto de clase como una función que devuelve una nueva instancia de clase. Por ejemplo, la creación de instancias del objeto de clase anterior es:
yrx = YuanRenXue()
Esto crea una nueva instancia de la clase y asigna la palabra objeto a la variable local yrx .
Una operación de creación de instancias se puede considerar como un objeto de clase "llamada". Pero todos queremos hacer algo de inicialización al crear una instancia de clase, podemos definir un método especial llamado __init__() para esta definición de clase. Es un método de inicialización para la creación de instancias de clase, similar al constructor en C ++.
def __init__(self):
self.data = None
Una vez que se define el método __init__() , el método es llamado automáticamente por la instanciación de la clase.
Por supuesto, el __init__() también puede tener parámetros adicionales (excepto uno mismo) para operaciones de inicialización más flexibles. Los parámetros pasados cuando se crea una instancia del objeto de clase (el objeto de clase "llamada") se pasan al método __init__() . Por ejemplo:
In [27]: class Point:
...: def __init__(self, x, y):
...: self.x = x
...: self.y = y
...:
In [28]: p = Point(7, 8)
In [29]: p.x, p.y
Out[29]: (7, 8)
Objeto de instancia
Una vez que se crea una instancia de la clase, obtenemos el objeto de instancia. La operación en él es: referencia de propiedad. Los nombres de atributos válidos aquí son atributos y métodos de datos.
o
El atributo de datos corresponde al "miembro de datos" en C ++. No importa si no entiendes a C ++. El nombre de "miembro de datos" es literalmente muy imagen. No es necesario declarar las propiedades de los datos. Se genera como la variable normal cuando se asigna por primera vez. Por ejemplo, p es una instancia de un Point creado por la declaración, el siguiente código imprimirá un valor de 8 :
p.times = 1
while p.times < 5:
p.times = p.times * 2
print(p.times)
del p.times
Aunque p.times no se declara en el momento de la definición de la clase (no es necesario declarar las propiedades de los datos), en cualquier momento, podemos asignar una nueva propiedad de datos a la instancia (aquí p.times ) y eliminar las propiedades de los datos de la instancia en cualquier momento. ( del p.times . del p.times ).
Un método es una función que depende de un objeto. El término método no es exclusivo de las instancias de clase, y otros objetos pueden tener métodos. Por ejemplo, los objetos de lista tienen métodos como append(), insert(), sort() etc.
El nombre de método válido de un objeto de instancia depende de la clase a la que pertenece. Por definición, todas las propiedades en una clase que son objetos de función son los métodos correspondientes que definen sus instancias. Entonces, en nuestro ejemplo, yrx.say_hi es una referencia de método válida porque YuanRenXue.say_hi es una función; yrx.name no es un método, porque YuanRenXue.name no es una función. Debería notarse aquí que YuanRenXue.say_hi no YuanRenXue.say_hi lo mismo que YuanRenXue.say_hi . Es un objeto de método, no un objeto de función. En general, el primero es un método de instancia y el último es una función de clase.
Objeto del método
Generalmente, el método de llamar a un método es:
yrx.say_hi()
En el ejemplo de YuanRenXue, esto imprimirá la cadena Hello World . Sin embargo, llamar a un método también se puede hacer de otra forma, asignándolo a una variable y luego llamándolo. Por ejemplo:
yrx_say = yrx.say_hi
yrx_say()
Cuando llamamos a yrx.say_hi() no hay ningún parámetro, pero la función say_hi()especifica un parámetro cuando está definido. De hecho, lo especial del método es que el objeto de instancia se pasa como el primer argumento (uno mismo) de la función. Llamar a yrx.say_hi() es equivalente a YuanRenXue.say_hi(yrx) .
Variables de clase y variables de instancia
En general, las variables de clase se usan para propiedades y métodos compartidos por todas las instancias de una clase, mientras que las variables de instancia se usan para datos únicos para cada instancia:
In [33]: class Tiger:
...: kind = 'feline'
...: def __init__(self, name)
File "<ipython-input-33-16aa1a5937d1>", line 3
def __init__(self, name)
^
SyntaxError: invalid syntax
In [34]: class Tiger:
...: kind = 'feline'
...: def __init__(self, name):
...: self.name = name
...:
In [35]: a = Tiger('Kiro')
In [36]: b = Tiger('Zim')
In [37]: a.kind
Out[37]: 'feline'
In [38]: b.kind
Out[38]: 'feline'
In [39]: a.name
Out[39]: 'Kiro'
In [40]: b.name
Out[40]: 'Zim'
Si una variable cuya variable de clase es una lista o un diccionario puede llevar a resultados sorprendentes, debemos entender el resultado para poder explotarlo cuando sea necesario, o evitarlo cuando no sea necesario. Es el resultado de la clase que queremos definir al programar. A continuación, veamos cuál es este resultado "sorprendente":
In [42]: class Tiger:
...: places = []
...: def __init__(self, name):
...: self.name = name
...: def go_place(self, place):
...: self.places.append(place)
...:
In [43]: a = Tiger('Kiro')
In [44]: b = Tiger('Zim')
In [45]: a.go_place('Pekín')
In [46]: b.go_place('Shangai')
In [47]: a.places
Out[47]: ['Pekín', 'Shangai']
Aquí, al definir los places como variables de clase, registra todos los tigres (Kiro y Zim, y los diversos tigres que se crearon posteriormente), por lo que aunque solo a estado en Beijing, cuando observamos places través de a También vimos Shanghai. Esta es la propiedad de un objeto mutable como una variable de clase. Si solo queremos registrar dónde han estado todos los objetos de la instancia de tiger, este uso es justo.
Si solo queremos registrar dónde ha estado cada tigre, entonces deberíamos definir places como variables de instancia, es decir, inicializar la asignación en __init__() .
Puntos a los que hay que prestar atención
(1) Los atributos de los datos anularán los atributos del método con el mismo nombre, por lo que para evitar conflictos de nombre al escribir programas, se pueden usar algunas especificaciones para reducir conflictos, tales como:
- Los nombres de los métodos usan letras mayúsculas;
- El nombre del atributo tiene un prefijo especial (o un guión bajo);
- Use verbos para nombrar métodos y sustantivos para nombrar atributos de datos.
Estas especificaciones se denominan "especificaciones de código" y una buena especificación de código hace que el código sea más legible y más colaborativo. La conocida especificación del código Python tiene "PEP 8" y la especificación del estilo Python de Google.
(2) Los atributos de los datos pueden ser referenciados por métodos y por cualquier usuario fuera del objeto (la persona que usa la clase). Es decir, Python no tiene miembros privados como las clases de C ++, y Python no tiene ningún objeto que pueda forzar la ocultación de los datos.
(3) Los usuarios de objetos de clase deben usar los atributos de datos con precaución, y la manipulación directa de los atributos de datos puede destruir variables fijas. Pero podemos pensar en un objeto de instancia para agregar nuestras propias propiedades de datos, pero evitar conflictos con el nombre original.
(4) El primer parámetro del método a menudo se denomina self , que representa el objeto de instancia. Pero esto es solo un acuerdo con el que todos están de acuerdo.Puede reemplazarlo con cualquier palabra, pero su código dificulta la lectura de los programadores de gas, y puede ser confuso para editores como VS Code.
Resumen
Las clases son métodos que combinan datos y funcionalidad, donde:
- Los datos, que es una propiedad de una clase, y dependen de varios objetos de datos de la clase;
- Las funciones, que son métodos de clases, definen varias funciones dentro de la clase.
Al definir una clase, creamos un objeto de clase que admite dos operaciones: referencia de propiedad e instanciación.
Una vez que se crea una instancia del objeto de clase, se obtiene el objeto de instancia. Tiene dos nombres de propiedades: propiedades de datos y métodos.
Las variables de clase son propiedades y métodos que son compartidos por instancias de todas las clases, y las variables de instancia son datos que son únicos para cada instancia.
留言
張貼留言