Notas de estudio de Python (5) -clase e instancia

1. Creación y uso sencillo

La clase puede reflejar la realidad

Código:

class Dog():  # 类名首字母大写
    """模拟小狗的简单测试"""

    def __init__(self, name, age):  # 该方法在类创建的时候会自动运行,类似java的构造函数,注意方法名开头和末尾各有两个下划线
        """初始化属性name和age"""
        self.name = name
        self.age = age

    def sit(self):  # 每个与类相关联的方法,都会传入参数self
        """模拟坐的动作"""
        print(self.name.title() + " 坐下")  # 可获取初始化方法中的值,因传递了参数self

    def roll(self, count):  # 可根据需求自定义要传入的参数,但是self是固定的
        """模拟打滚的动作"""
        print(self.name.title() + " 滚了 " + str(count) + " 圈")


my_dog = Dog('二哈', 3)  # 此处要传入类的初始化方法里的参数
print("我的小狗名字是:" + my_dog.name + "\n年龄是:" + str(my_dog.age))
my_dog.sit()
my_dog.roll(4)  #传入自定义的count参数

resultado:

我的小狗名字是:二哈
年龄是:3
二哈 坐下
二哈 滚了 4 圈

2. Usa clases e instancias

Primero crea una clase de automóvil

class Car():
    """模拟汽车"""

    def __init__(self, make, model, year=2016):  # 默认时间为2016,如果指定参数了,则按照传入的参数处理,同上一章内容
        """初始化汽车数据"""
        self.make = make
        self.model = model
        self.year = year

    def describe(self):
        """返回描述信息"""
        message = "车类别:" + self.make + " 车型号:" + self.model + " 制造时间:" + str(self.year)
        return message  # 也可以直接打印


my_car_1 = Car('奥迪', 'R8', 2015) # 指定时间参数是2015
my_car_2 = Car('宝马', 'Z7') # 再创建一个实例,没有指定时间参数
print(my_car_1.describe())
print(my_car_2.describe())

resultado:

车类别:奥迪 车型号:R8 制造时间:2015
车类别:宝马 车型号:Z7 制造时间:2016

Modificar el valor del atributo de la instancia creada

( Nota: después de la modificación, solo se cambia el valor de atributo de la instancia y los valores de atributo de otras instancias creadas por la misma clase no se ven afectados )

Código:

class Car():

    # --snip--

# 修改属性的值,直接访问修改,也可将该逻辑写在类创建的一个函数中,直接调用修改
my_car_1.year = 2000  # 制造时间改为2000年
print(my_car_1.describe())
my_car_1.color = 'red' # 增加属性的值,直接赋值给新属性即可,同字典
print(my_car_1.color)
print(my_car_2.color)  # 此句报错,因为car2并没有color属性

resultado:

车类别:奥迪 车型号:R8 制造时间:2000  
red
AttributeError: Car instance has no attribute 'color'

3. Restricciones de acceso a clases

Hay símbolos de control de acceso en java, public,privatey hay símbolos de control en atributos en Python, en las siguientes clases.

Código:

class Person():
    def __init__(self, name, age):
        self.__name = name  # 由两个下划线开始的属性表示类的私有属性,外部无法正常访问
        self.__age = age

    def say(self):  # 私有属性只能自己内部访问
        print ('name:' + self.__name + 'age:' + str(self.__age))


p1 = Person('吴彦祖 ', 18)
p1.say()
print (p1.__name) # 此句报错,同理,无法修改相应属性

resultado:

name:吴彦祖 age:18
AttributeError: Person instance has no attribute '__name'

Igual que java, si desea acceder o modificar externamente, puede crear set()y get()método dentro de la clase , de la siguiente manera

Código: ( nuevo conjunto y métodos de obtención agregados a la clase )

class Person():

    # --snip--

    def set_name(self, name):  # 可在方法中控制,避免修改成无效的数据
        self.__name = name

    def get_name(self):
        return self.__name

p1 = Person('吴彦祖', 18)  #  获取实例
print (p1.get_name())  # 访问属性
p1.set_name('刘德华') # 修改属性
print (p1.get_name()) # 访问属性

resultado:

吴彦祖
刘德华

Sugerencia: A veces encontrarás variables que comienzan con un solo guión bajo, por ejemplo _name, significa que se recomiendan como variables privadas, pero aún se puede acceder a ellas de manera externa (no sé cómo diseñarlo para Mao, así que recuérdalo por ahora y modifícalo más tarde si lo sabes)

Las variables privadas que comienzan con un guión bajo doble son realmente accesibles desde afuera, por ejemplo

p1._Person__name

Es porque el atributo __name está encapsulado dentro de la clase de Python, pero no se recomienda escribir esto, porque diferentes versiones de los intérpretes de Python pueden cambiar __name a diferentes nombres de variable.

Lo último a tener en cuenta es: al agregar y modificar atributos, no puede agregar ni modificar atributos privados. P.ej

p1 = Person('吴彦祖', 18)
p1.__name = '刘德华'  # 本意修改name的值
print (p1.get_name()) # 实际上并未修改
print (p1.__name) # 只是新增添了__name属性

resultado:

吴彦祖
刘德华

Pero se puede p1._Person__namemodificar por método, pero no se recomienda por la misma razón que la anterior.

4. Herencia

1. Cuando se crea la subclase, se debe llamar al método de la clase principal en el método de inicialización para __init__()obtener todas las propiedades y métodos de la clase principal. También puede definir sus propias propiedades y métodos únicos y anular el
código de la clase principal  :

class ElectricCar(Car):  # 继承父类时,将父类写入括号内即可
    """电动车"""

    def __init__(self, make, model, year):
        """初始化父类的属性"""
        super().__init__(make, model, year)  # 注意super的括号,→_→
        # 初始化自己独有的属性
        self.battery = 70

    # 定义独有的方法
    def describe_battery(self):
        print("电池容量:" + str(self.battery))


my_tesla = ElectricCar('特斯拉', 'S', 2011)
print(my_tesla.describe())
my_tesla.describe_battery()

resultado:

车类别:特斯拉 车型号:S 制造时间:2011
电池容量:70

2. Anula el método de la clase principal, similar a java, la instancia solo ejecuta el método del mismo nombre de la subclase

Si hay fill_gasmétodos en la clase Car , pero no tienen sentido para la subclase de autos eléctricos, la subclase ElectricCar puede anular los fill_gasmétodos de la superclase y dar consejos amigables. 
Código:

class ElectricCar(Car):  # 继承父类时,将父类当做参数

    # --snip--

    # 重写父类的方法,方法名相同
    def fill_gase_tank(self):
        """电动车没有汽油"""
        print("电动车不需要加油,你四不四洒.")

# --snip--
my_tesla.fill_gase_tank()

resultado:

电动车不需要加油,你四不四洒.

3. Puedes usar la instancia como atributo de una clase.

Por ejemplo, cree una nueva clase de batería

class Battery():
    """电池类"""

    def __init__(self, battery_size=10):  #默认10
        self.battery_size = battery_size

    def describle(self):
        print("电池容量是:" + self.battery_size)

Pase la clase Battery como parámetro a la clase ElectricCar y modifique el
código del método de inicialización de la clase ElectricCar  :

def __init__(self, make, model, year):
    """初始化父类的属性"""
    super().__init__(make, model, year)  
    # 初始化自己独有的属性
    self.battery = Battery()  # 此处直接新建Battery的实例赋值给battery属性,没有参数传递,使用默认值10


Código al llamar  :

my_tesla.battery.describle()

resultado:

电池容量是:10

4. Polimorfismo y tipo de pato de pitón

Polimorfismo en Java, la clase principal define un método A, y la subclase tiene un método A con el mismo nombre. Si el parámetro pasado para llamar a otros métodos B de la clase principal (llamada A) es el tipo de la clase principal, llame a la subclase correspondiente Método de nombre duplicado. P.ej

Código:

class A():
    def say(self): # A中有方法say()
        print ('A说话了')

    def say_twice(self, A): # 调用say方法,但是传入A类型的数据
        A.say()
        A.say()


class B(A):  # B中有方法say()
    def say(self):
        print ("B说话了")


class C(A):  # C中有方法say()
    def say(self):
        print ("C说话了")

a = A()
b = B()
c = C()

a.say_twice(b) # 调用A的say_twice方法,传入子类b的实例,因为b继承自A,所以调用b的say方法
a.say_twice(c) # 同上

resultado:

B说话了
B说话了
C说话了
C说话了

Debido a que java es un lenguaje estático, el tipo de datos pasado en el método de la clase definida, es decir, el tipo de datos requerido por el símbolo se puede pasar, mientras que Python es un lenguaje dinámico, siempre que la clase tenga un método con el mismo nombre (digamos () en el código anterior) , Puede pasar una instancia de esta clase, por ejemplo, definir una clase D, incluido el método say

Código:

class D():
    def say(self):
        print ('D没继承,照样说话了')

d = D()
a.say_twice(d)  #  传入D的实例d,虽然没有继承A,但是有say方法,同样可以执行D的say方法,若不包含say方法,则这样调用报错

resultado:

D没继承,照样说话了
D没继承,照样说话了

Tal tipo es un tipo de pato (parece un pato, es un pato → _ → no sé cómo usar un pato para el pelo)

5. Importa la clase

Similar a la función de importación anterior, use la from xxx impoort xxxdeclaración

from car import Car  # 第一个car是car.py文件,第二个Car是类,即从某个.py文件中导入某个类
from car import Car, ElectricCar #导入多个类,用逗号分开
import car # 或者直接导入整个模块,同上一章,使用的时候用 car.xxx
from car import * #导入某个模块的所有类和方法,不建议这样用,可能会和当前文件的某些类或者函数名重合导致出错

6, biblioteca estándar de Python

La biblioteca estándar de Python es un conjunto de módulos que vienen con el sistema, que contienen muchos
códigos de método de uso común  :

from collections import OrderedDict # 导入有序字典

users_age = OrderedDict()  # 返回一个有序的字典

users_age['大娃'] = 1 
users_age['二娃'] = 2
users_age['三娃'] = 3


for name, age in users_age.items():
    print("名字是:" + name + " 年龄是:" + str(age))

Resultado:  salida en el orden de adición

名字是:大娃 年龄是:1
名字是:二娃 年龄是:2
名字是:三娃 年龄是:3

 

Supongo que te gusta

Origin blog.csdn.net/weixin_38452841/article/details/108368378
Recomendado
Clasificación