0x013.Python orientado a objetos de aprendizaje

 

Python3 orientado a objetos

No hay mucho que decir, primero obtengamos un montón de conocimientos teóricos, solo use ctrl + F

Python ha sido un lenguaje orientado a objetos desde su diseño, por lo que es fácil crear una clase y un objeto en Python. En este capítulo, presentaremos en detalle la programación orientada a objetos de Python.

Si no ha estado expuesto a lenguajes de programación orientados a objetos antes, es posible que deba comprender algunas de las características básicas de los lenguajes orientados a objetos y formar un concepto básico orientado a objetos en su mente, que le ayudará a aprender Python más fácilmente Programación orientada a objetos.

A continuación, comprendamos brevemente algunas de las características básicas del siguiente objeto.


Introducción a la tecnología orientada a objetos

  • Clase: se  utiliza para describir una colección de objetos con las mismas propiedades y métodos. Define los atributos y métodos comunes a cada objeto de la colección. Los objetos son instancias de clases.
  • Método: La función definida en la clase.
  • Variables de clase: las variables de clase son comunes en todo el objeto instanciado. Las variables de clase se definen en la clase y fuera del cuerpo de la función. Las variables de clase generalmente no se utilizan como variables de instancia.
  • Miembros de datos: las variables de clase o de instancia se utilizan para procesar datos relacionados con la clase y sus objetos de instancia.
  • Reescritura de método: si el método heredado de la clase principal no puede satisfacer las necesidades de la clase secundaria, se puede reescribir. Este proceso se denomina anulación de método, también conocido como reescritura de método.
  • Variable local: la variable definida en el método solo actúa sobre la clase de la instancia actual.
  • Variables de instancia: en la declaración de una clase, los atributos se representan mediante variables. Estas variables se denominan variables de instancia, que se declaran dentro de la declaración de la clase pero fuera de los otros métodos miembros de la clase.
  • Herencia: es decir, una clase derivada hereda los campos y métodos de la clase base. La herencia también permite que un objeto de una clase derivada se trate como un objeto de clase base. Por ejemplo, existe un diseño de este tipo: un objeto de tipo Perro se deriva de la clase Animal, que simula una relación "es-a" (diagrama de ejemplo, Perro es un animal).
  • Creación de instancias: crea una instancia de una clase, un objeto específico de la clase.
  • Objeto: instancia de una estructura de datos definida por una clase. El objeto incluye dos miembros de datos (variables de clase y variables de instancia) y métodos.

En comparación con otros lenguajes de programación, Python agrega un mecanismo de clase sin agregar nueva sintaxis y semántica tanto como sea posible.

Las clases en Python proporcionan todas las funciones básicas de la programación orientada a objetos: el mecanismo de herencia de la clase permite múltiples clases base, las clases derivadas pueden cubrir cualquier método en la clase base y los métodos con el mismo nombre en la clase base se pueden llamar en el método.

Los objetos pueden contener cualquier cantidad y tipo de datos.

Métodos específicos de clase:

  • __init__:  Constructor, llamado cuando se genera el objeto
  • __del__:  Destructor, usado al soltar el objeto
  • __repr__:  imprimir, convertir
  • __setitem__:  Asignar valor según índice
  • __getitem__:  Obtiene el valor según el índice
  • __len__:  obtenga la longitud
  • __cmp__:  operación de comparación
  • __call__:  llamada de función
  • __add__:  operación de adición
  • __sub__:  operación de resta
  • __mul__:  Multiplicación
  • __truediv__:  operación de división
  • __mod__:  operación de resto
  • __pow__:  poder
针对 __str__ 方法给出一个比较直观的例子:
class people:
    def __init__(self,name,age):
        self.name=name
        self.age=age

    def __str__(self):
        return '这个人的名字是%s,已经有%d岁了!'%(self.name,self.age)

a=people('孙悟空',999)
print(a)
输出:
这个人的名字是孙悟空,已经有999岁了!
如果没有重载函数的话输出的就是一串看不懂的字符串:
<__main__.people object at 0x00000272A730D278>
最新的 Python3.7 中(2018.07.13),对类的构造函数进行了精简。
3.7 版本:
from dataclasses import dataclass
@dataclass
class A:
  x:int
  y:int
  def add(self):
    return self.x + self.y
相当于以前的:
class A:
  def __init__(self,x,y):
    self.x = x
    self.y = y
  def add(self):
    return self.x + self.y
静态方法: 用 @staticmethod 装饰的不带 self 参数的方法叫做静态方法,类的静态方法可以没有参数,可以直接使用类名调用。
普通方法: 默认有个self参数,且只能被对象调用。
类方法: 默认有个 cls 参数,可以被类和对象调用,需要加上 @classmethod 装饰器。
class Classname:
    @staticmethod
    def fun():
        print('静态方法')

    @classmethod
    def a(cls):
        print('类方法')

    # 普通方法
    def b(self):
        print('普通方法')



Classname.fun()
Classname.a()

C = Classname()
C.fun()
C.a()
C.b()
selfeasy
   selfeasy



反向运算符重载:
__radd__: 加运算
__rsub__: 减运算
__rmul__: 乘运算
__rdiv__: 除运算
__rmod__: 求余运算
__rpow__: 乘方
复合重载运算符:
__iadd__: 加运算
__isub__: 减运算
__imul__: 乘运算
__idiv__: 除运算
__imod__: 求余运算
__ipow__: 乘方
运算符重载的时候:
#!/usr/bin/python3

class Vector:
    def __init__(self, a, b):
        self.a = a
        self.b = b
    def __str__(self):
        return 'Vector (%d, %d)' % (self.a, self.b)

    def __repr__(self):
        return 'Vector (%d, %d)' % (self.a, self.b)

    def __add__(self,other):
        if other.__class__ is Vector:
            return Vector(self.a + other.a, self.b + other.b)
        elif other.__class__ is int:
            return Vector(self.a+other,self.b)

    def __radd__(self,other):
        """反向算术运算符的重载
        __add__运算符重载可以保证V+int的情况下不会报错,但是反过来int+V就会报错,通过反向运算符重载可以解决此问题
        """

        if other.__class__ is int or other.__class__ is float:
            return Vector(self.a+other,self.b)
        else:
            raise ValueError("值错误")

    def __iadd__(self,other):
        """复合赋值算数运算符的重载
        主要用于列表,例如L1+=L2,默认情况下调用__add__,会生成一个新的列表,
        当数据过大的时候会影响效率,而此函数可以重载+=,使L2直接增加到L1后面
        """

        if other.__class__ is Vector:
            return Vector(self.a + other.a, self.b + other.b)
        elif other.__class__ is int:
            return Vector(self.a+other,self.b)
v1 = Vector(2,10)
v2 = Vector(5,-2)
print (v1 + v2)
print (v1+5)
print (6+v2)
Python3 类方法总结
 普通方法:对象访问
 私有方法:两个下划线开头,只能在类内部访问
 静态方法:类和对象访问,不能和其他方法重名,不然会相互覆盖,后面定义的会覆盖前面的
 类方法:类和对象访问,不能和其他方法重名,不然会相互覆盖,后面定义的会覆盖前面的
 多继承情况下:从左到右查找方法,找到为止,不然就抛出异常
class People:

    # 定义基本属性
    name=''
    age=0
    # 定义私有属性外部无法直接访问
    __weight=0
    def __init__(self,n,a,w):
        self.name = n
        self.age = a
        self.__weight = w
    def speak(self):
        print("%s say : i am %d."%(self.name,self.age))
p = People('Python',10,20)
p.speak()
# __weight无法直接访问
print(p.name,'--',p.age)#,'--',p.__weight)
继承
单继承:
class Student(People):
    grade=''
    def __init__(self,n,a,w,g):
        People.__init__(self,n,a,w)
        self.grade = g

    # 覆写父类方法
    def speak():
        print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))

class Speak():
    topic=''
    name=''
    def __init__(self,n,t):
        self.name = n
        self.topic = t
    # 普通方法,对象调用
    def speak(self):
        print("我叫 %s,我是一个演说家,我演讲的主题是 %s"%(self.name,self.topic))

    # 私有方法,self调用
    def __song(self):
        print('唱一首歌自己听',self);

    # 静态方法,对象和类调用,不能和其他方法重名,不然会相互覆盖,后面定义的会覆盖前面的
    @staticmethod
    def song():
        print('唱一首歌给类听:静态方法');

    # 普通方法,对象调用
    def song(self):
        print('唱一首歌给你们听',self);
        
    # 类方法,对象和类调用,不能和其他方法重名,不然会相互覆盖,后面定义的会覆盖前面的
    @classmethod
    def song(self):
        print('唱一首歌给类听:类方法',self)
多继承:
class Sample(Speak,Student):
    a = ''
    def __init__(self,n,a,w,g,t):
        Student.__init__(self,n,a,w,g)
        Speak.__init__(self,n,t)
test = Sample('Song',24,56,7,'Python')
test.speak()
test.song()
Sample.song()
Sample.song()
test.song()

# test.__song() 无法访问私有方法
类的二元方法运算符重载介绍的并不全面,文中介绍的全是正向方法,其实还有反向方法,就地方法。下面补充一些。
当解释器碰到 a+b 时,会做以下事情:
从 a 类中找 __add__ 若返回值不是 NotImplemented, 则调用 a.__add__(b)。
若 a 类中没有 __add__ 方法,则检查 b 有没有 __radd__ 。如果如果有,则调用 b.__radd__(a),若没有,则返回 NotImplemented。
接上条,若 b 也没有 __radd__ 方法,则抛出 TypeError,在错误消息中知名操作数类型不支持。
比如:向量类 <Myvector> 应当有向量与整数的乘法:
>>>a = Myvector([1,2,3])
>>>print(a.value)
[1,2,3]
>>>b=3
>>>c = a*b   #此时调用Myvector.__mul__()
>>>print(c.value)
[3,6,9]
>>> d=b*a  #这句会出错。
期望得到 b*a 也返回一个向量,b*a 应该等于 a*b。此时就需要在 Myvector 类中定义一个__rmul__方法。
def __rmul__(self, other):
    if isinstance(other, int):
        return Myvector([a*other for a in self.m])
每个运算符都有正向方法重载,反向方法重载。有一些有就地方法(即不返回新的对象,而是修改原本对象)。

 

 

class Ren:
    name ="zhangsan"
    age =20
    sex ='man'
    def run(self):
        print 'basketball'

class Ren:
    name ="zhangsan"      #变量
    age =20
    sex ='man'
    def run(self,x):        #函数
        print 'basketball'
        print x
zhang =Ren()                  #创建对象的过程叫实例化,zhang为对象
print zhang.name
zhang.run('xxxxxxxxxx')       #对象的方法
zhang.age =40                 #设置属性
print zhang.age
zhang.job ='it'               #添加属性
print zhang.job

 

class Ren:
    name ="zhangsan"      #变量
    age =20
    sex ='man'
    __tt ='zs'
    def run(self,x):        #函数
        print 'basketball'
        print x
        print self.__tt       #内部调用私有属性
zhang =Ren()                  
print zhang.name
zhang.run('xxxxxxxxxx')     
zhang.age =40                 
print zhang.age
zhang.job ='it'               
print zhang.job
print zhang._Ren__tt          #调用内部私有类

 

#! /usr/bin/python
# ! -*- coding: UTF-8 -*-

class Ren:
    name = "zhangsan"  # 变量
    age = 20
    sex = 'man'
    __tt = 'zs'

    def run(self, x):  # 函数
        print 'basketball'
        print x
        print self.__tt  # 内部调用私有属性

    def __kk(self, x):  # 函数
        print 'running'
        print self.__tt  # 内部调用私有属性

    @classmethod #函数修饰符 或者声明称静态函数@staticmethod,静态函数就不需要加参数了,即无须self
    def hel(self): #@classmethod 相当于把run函数加载到classmethod里面运行,即run =@classmethod(run)
        print "hel man!"  # 使用私有方法进行调用测试


zhang = Ren()  # 创建对象的过程叫实例化,zhang为对象
print zhang.name
zhang.run('xxxxxxxxxx')  # 对象的方法
zhang.age = 40  # 设置属性
print zhang.age
zhang.job = 'it'  # 添加属性
print zhang.job
print zhang._Ren__tt  # 调用内部私有类
zhang._Ren__kk("私有方法调用")
zhang.hel()  # 公有方法
Ren.hel()    #私有方法调用

 

 

 

class Ren:

    class Badren: #Internal class
        name = 'huairen'
        @classmethod
        def badshi (self):
            print'papapa '
huairen = Ren.Badren #Instantiate the internal class
print huairen.name #En las variables de la clase interna Call
huairen .badshi () #

class Ren:
    def __init __ (self, x):
        print'Constructor: Al instanciar un objeto, el constructor se ejecutará por defecto, es decir, al instanciar, primero llame al constructor
        'print'xxxxxxxxxx:', x # Al instanciar un objeto, pasarle parámetros e implementarlo a través del constructor
zhang = Ren ("zhangsan") # Al crear una instancia de un objeto, pasarle parámetros e implementarlo a través del constructor

#f = open ('c: \ 1.txt', 'r') #En un formato de solo lectura, instanciar la función f, operaciones de archivo

class Ren:
    name = "zhangsan"  # 变量
    age = 20
    sex = 'man'
    __tt = 'zs'
    def __del__(self): #析构函数
        f = open('c:\1.txt', 'r')
        f.read()
        f.close()

 

 

class Parent:
    name ='lisi'
    parentAttr = 100
    def fulei(self):
        print '这是父类中的方法'
    def __init__(self):
        print "这是父类中构造函数,私有化方法"
class Child(Parent):#子类调用父类
    name ='lisi'
    def childMethod(self):
        print '这是子类中的方法'
child =Child()#实例化子类
child.fulei()#子类调用父类中的方法
child.childMethod()#调用子类中本身的方法
print child.name #(子类父类中同有的变量),子类调用时,优先权会高于父类,输出lisi 

Código total de Lession13:

#! /usr/bin/python
# ! -*- coding: UTF-8 -*-
#【继承】
#父类有的,继承后子类可以直接调用
#父类子类都有同一个重名函数,优先子类调用自己的
#父类只能调用自己的函数
class Ren:
    name = "zhangsan"  # 变量
    age = 20
    sex = 'man'
    __tt = 'zs'
    def __del__(self): #析构函数
        f = open('c:\1.txt', 'r')
        f.read()
        f.close()
'''
    def __init__(self,x):
        print '构造函数:当实例化对象的时候,构造函数就会被默认执行,即实例化的时候,先调用构造函数'
        print 'xxxxxxxxxx:',x #实例化对象的时候,对其进行传参,通过构造函数实现
zhang =Ren("zhangsan")#实例化对象的时候,对其进行传参,通过构造函数实现

#f =open('c:\1.txt','r') #以只读的形式,实例化函数f ,文件操作


     def run(self, x):  # 函数
        print 'basketball'
        print x
        print self.__tt  # 内部调用私有属性

    def __kk(self, x):  # 函数
        print 'running'
        print self.__tt  # 内部调用私有属性

    @classmethod #函数修饰符 或者声明称静态函数@staticmethod,静态函数就不需要加参数了,即无须self
    def hel(self): #@classmethod 相当于把run函数加载到classmethod里面运行,即run =@classmethod(run)
        print "hel man!"  # 使用私有方法进行调用测试

    class Badren: #内部类
        name ='huairen'
        @classmethod
        def badshi(self):
            print 'papapa'


zhang = Ren()  # 创建对象的过程叫实例化,zhang为对象
print zhang.name
zhang.run('xxxxxxxxxx')  # 对象的方法
zhang.age = 40  # 设置属性
print zhang.age
zhang.job = 'it'  # 添加属性
print zhang.job
print zhang._Ren__tt  # 调用内部私有类
zhang._Ren__kk("私有方法调用")
zhang.hel()  # 公有方法
Ren.hel()    #私有方法调用
huairen =Ren.Badren #对内部类进行实例化 或者是huairen=zhang.Badren
print huairen.name #对内部类里面的变量进行调用
huairen.badshi() #对内部类的方法进行调用
'''
class Parent:
    name ='lisi'
    parentAttr = 100
    def fulei(self):
        print '这是父类中的方法'
    def __init__(self):
        print "这是父类中构造函数,私有化方法"
class Child(Parent):#子类调用父类
    name ='lisi'
    def childMethod(self):
        print '这是子类中的方法'
child =Child()#实例化子类
child.fulei()#子类调用父类中的方法
child.childMethod()#调用子类中本身的方法
print child.name #(子类父类中同有的变量),子类调用时,优先权会高于父类,输出lisi
class sson(Child):
    print '我是孙子类,测试能否继承爷爷类'
sson =sson()#并且实例化对象时,会再次加载构造函数
sson.fulei()# 结果测试可以继承

Indique: Blog de Adminxe  »  0x013. Orientado a objetos de aprendizaje de Python

Supongo que te gusta

Origin blog.csdn.net/Adminxe/article/details/106679052
Recomendado
Clasificación