1.9 - 面向对象编程

1.9.1 Python实例化对象的过程

  p = Person('zhangsan',  14,  'guangzhou')实例化对象的时候,首先会触发 __new__(cls,  *args,  **kwargs)  魔术方法,生成实例对象并将实例化参数一同返回给p,然后会自动触发 __init__(self, name,age,adress) 魔术方法,进行实例属性初始化(属性定制)。【先实例化,再初始化属性。

  python在初始化子类属性的时候,如果子类重写了__init__方法那么程序 只会执行 子类的__init__方法,如果子类没有自定义__init__方法,则会调用父类的__init__方法。

  魔术方法:以 双下划线开头且双下划线结尾 的 官方定义的 方法。特点是:一般不需要主动调用,会在特定条件下自动触发。

1.9.2 初始化、动态新增、删除 类属性和实例属性

# 类属性与实例属性

class Teacher(object):
    # 类属性, 该属性属于类,调用时一般  类名.类属性名,也可以 实例名称.类属性名 的方式调用。
    school = 'DUT'

    # 实例属性,该部分属性隶属于实例。
    def __init__(self, name, age):
        self.name = name
        self.age = age

t1 = Teacher('zhangSan', 14)
t2 = Teacher('lisi', 15)

print(t1.name,  t1.age,  Teacher.school, t1.school)
print(t2.name,  t2.age,  Teacher.school, t2.school) 

# 动态新增类属性
Teacher.info = 'hello world'
# 动态新增实例属性
t1.company = 'xx'

# 删除实例属性
del t1.name, t2.age
# 删除类属性
del Teacher.info

   在 __init__() 方法中通过 self 初始化的实例属性,都会归结到实例对象中,即便其属性名称和类属性名称相同,也不会互相混淆,而是各自调用各自的。

   仅以 双下划线开头的属性或方法 为私有,只在类内可见,外部不可见的实现方式:解释器会在类内修改私有属性或方法的名称,因此外部调用不可见,而类内部调用可见(如:类内的私有属性__age ,会在实际中命名为 _className__age)。

1.9.3 实例方法、类方法、静态方法

# 实例方法、类方法、静态方法

class Teacher:
    # 魔术方法,官方定义的方法,以 双下划线开头且结尾,不必调用但会在特定情况下自动触发执行
    def __init__(self, name):
        self.name = name
    
   # 实例方法定义
    def say(self, info):
        print(info)

    # 类方法定义
    @classmethod
    def say(cls, info):
        print(info)

    # 静态方法定义
    @staticmethod
    def say():
        print('this is a static method')


# 方法的调用
t = Teacher('张老师') 
t.say('hello, instance method')  # 实例方法调用
Teacher.say('hello, class method')  # 类方法调用

  如果定义了同名的类属性和实例属性,那么各自调用各自的;如果定义了同名的实例方法和类方法,那么后面的方法会覆盖前面的( python顺序逐行执行 )。

实例方法归属于某个实例,在定义实例方法的时候会在首个位置强制传入self参数,self参数代表 该方法的实际对象实例引用;

类方法归属于本类及子类,在定义类方法的时候会在首个位置强制传入cls参数,cls的含义是 方法调用者的实际引用实例(包含本类及子类),例如:子类调用父类的方法且子类没有重写,cls则指代子类实例对象(这样当该方法中会调用子类的属性,更符合多态的特性)。在有继承关系的结构中更灵活。

静态方法归属于本类,在定义静态方法的时候不强制传入参数,所以方法内调用属性的时候,只能通过 类名.类属性名 的方式调用属性,无法触及到子类实例属性。

1.9.4 Python的多继承

# Python的继承

class A:
    def __init__(self, a):
        self.a = a

class B:
    def __init__(self, b):
        self.b = b

class D:
    def __init__(self, d):
        self.d = d

class C(A, B):
    
    def __init__(sefl, c):
        self.c = c
        super(C, self).__init__(a) = 'xxx'

  Python多继承:class Cat(Pet, Catumn): pass  实例化Cat之后,如果Cat实例调用的方法在Cat中不存在,则会在继承的多个类中,从左向右 依次寻找该方法,比如:会首先寻找Pet类及其所有父类中的方法,再寻找Catumn类及其所有父类中的方法。

  类名.__mro__  返回类的继承顺序

  调用父类的方法: super(X,  d).method()  # 表示 调用类X的父类的method方法,调用实例对象为 d。

  

  isinstance(obj,  单个类或多个类组成的元组):判断是否是实例,有继承关系的

  type(obj,  cls), 判断 对象是否是某个类,且  必须是该类而不能是该类的子类。

 

   不同文件中的类之间有继承关系:

    继承的时候需要:

      from  文件名(即:模块名)  import 类名。 Python中,一个文件即是一个模块,一个文件中可以定义多个不同的类,且文件名和类名之间互不关联

 

posted @ 2024-01-16 17:28  橘子葡萄火龙果  阅读(14)  评论(0)    收藏  举报