美文网首页
20 类相关

20 类相关

作者: 代码小小白 | 来源:发表于2021-03-02 11:56 被阅读0次

1.类指针:子类找父类,实例找类都是通过自身携带的类指针去寻找。


类指针.png

2.Python3中所有的类都继承于Object类,可以省略不写,Python2不写继承Object类的话就是经典类。新式类和经典类的区别就是继承顺序。

在下图例子中 类的继承.png

① 经典类中是深度优先 :A->B->C->D->E->F
② 新式类中是广度优先(继承顺序按照C3算法,了解有这个算法即可):A-B-C-E-F-D
③ 在Python中可以利用mro()函数查看类的继承顺序

3.Python中是有多继承的,Java中只有单继承

4.多态:
① 在python中所有类都是多态的
② 在Java中,如果一个函数或者类,需要传入不同的类型B和C,那么B和C必须继承同一个类A,那么我们可以说传入的类型都为A,B和C是类型A表现出来的不同类型。

5.super方法:
① 在单继承中,super就是调用父类的方法

class User:
    def __init__(self,name):
        self.name = name
class VIPUser(User):
    def __init__(self,name,level,strat_date,end_date):
        # User.__init__(self,name)
        super().__init__(name)              # 推荐用法
        # super(VIPUser,self).__init__(name)
        self.level = level
        self.strat_date = strat_date
        self.end_date = end_date

② 在多继承中就是,按照mro的顺序寻找下个类中的同名方法

class A(object):
    def func(self):
        print('A')
class B(A):
    def func(self):
        super().func()
        print('B')
class C(A):
    def func(self):
        super().func()
        print('C')
class D(B,C):
    def func(self):
        super().func()
        super(D,self).func()
        print('D')

# 分析:D().func(),先搞清mro的顺序D->B->C->A->obj
# A-C-B-A-C-B-D

6.封装:
① 在类的静态变量,实例变量,实例方法加上两个下划线,就会变成私有的

class User:
     __Country = 'China'   # 私有的静态变量
     __Role = '法师'   # 私有的静态变量
     def func(self):
         print(self.__Country)  # 在类的内部使用的时候,自动的把当前这句话所在的类的名字拼在私有变量前完成变形
print(User._User__Country)
print(User._User__Role)
# __Country -->'_User__Country': 'China'
# __Role    -->'_User__Role': '法师'
# User.__aaa = 'bbb'  # 在类的外部根本不能定义私有的概念

② 私有的变量不能被子类使用

7.property,setter,deleter装饰器
① property装饰器,把一个方法伪装成一个属性,在调用这个方法的时候不需要加()就可以直接得到返回值。什么时候用@property装饰器呢?举个例子,在一个圆形类中,有属性半径r,有函数area,这个函数返回的是面积。其实这个面积和半径一样,可以看做这个圆形类中的一个属性,那么这个时候就可以用@property装饰器。

from math import pi
class Circle:
    def __init__(self,r):
        self.r = r
#     @property   # 把一个方法伪装成一个属性,在调用这个方法的时候不需要加()就可以直接得到返回值
    def area(self):
        return pi * self.r**2
c1 = Circle(5)
print(c1.r)
print(c1.area)

② setter deleter装饰器

class Goods:
    discount = 0.8
    def __init__(self,name,origin_price):
        self.name = name
        self.__price = origin_price
    @property
    def price(self):
        return self.__price * self.discount

# @后面的名字必须和函数名字相同
    @price.setter
    def price(self,new_value):
        if isinstance(new_value,int):
            self.__price = new_value

    @price.deleter
    def price(self):
        del self.__price
apple = Goods('apple',5)
print(apple.price)
apple.price = 'ashkaksk' # 调用了@price.setter装饰的方法
del apple.price   # 并不能真的删除什么,只是调用对应的被@price.deleter装饰的方法而已
print(apple.price)

8.反射
概念:用字符串数据类型的名字 来操作这个名字对应的函数\实例变量\绑定方法\各种方法
常见的反射:
① 反射对象的 实例变量/绑定方法
② 反射类的 静态变量/其他方法
③ 模块中的 所有变量(被导入模块和本模块)

# 反射
import sys
# getattr, hasattr

class Person:
    Role = "法师"
    def __init__(self, name, age):
        self.name = name
        self.age = age

    @staticmethod
    def sing():
        return "我唱歌"


xm = Person(name="xiaoming", age=18)

# 访问对象xm的实例方法
name1 = xm.name
name2 = getattr(xm, "name") # 通过字符串的方法去访问
role = getattr(Person, "Role") # 通过字符串访问类的静态属性
s = getattr(Person, "sing") # 通过字符串访问类的静态方法
print(name1, name2, role, s())

def pig():
    print('小p')
# 反射本模块的中的函数,如果是反射其他模块的,只需把第一个参数换成模块名
getattr(sys.modules['__main__'], "pig")()

9.两个装饰器 @classmethod 和 @staticmethod
① @classmethod :把一个对象绑定的方法 修改成一个 类方法

# 可以通过类名.方法名的方式调用,也可以实例.方法名的方式调用
# 什么时候用:我的理解是在在方法内部需要用到类名的时候

# 下面例子通过已知分数查看学生的level属性,在handle_score函数中直接返回了Students的对象,用到了类名,所以这时候用@classmethod
class Students:
    def __init__(self, name, age, level):
        self.name = name
        self.age = age
        self.level = level

    @classmethod
    def handle_score(cls, name, age, score):
        if score >= 60:
            return cls(name, age, "及格")
        else:
            return cls(name, age, "不及格")

stu = Students.handle_score("小明", 18, 60)
print(stu.level)

② @staticmethod:被装饰的方法会成为一个静态方法,这种常常是因为为了代码结构的完整性,将用不到self和cls的函数写在类中。

10.Python中的一些魔法方法

# __call__
# 一个对象如果是callable的,那么这个对象一定有__call__属性
class A:
    def __call__(self, *args, **kwargs):
        print('!!!-------')
A()()  #  调用A的实例中的 __call__ 方法,输出:!!!-------

# __len__
# 如果想通过len(obj)的方式去获取一个实例中参数的个数,那么这个类中一定要实现__len__方法
class Cls:
    def __init__(self,name):
        self.name = name
        self.students = []
    def len(self):
        return len(self.students)
    def __len__(self):
        return len(self.students)
py22 = Cls('py22')
py22.students.append('杜相玺')
py22.students.append('庄博')
py22.students.append('大壮')
print(py22.len()) # 执行类中__len__方法
print(len(py22)) #执行类中__len__方法

#__new__
#负责创建类的实例,并且先于__init__方法执行(通常情况下是使用 super(类名, cls).new(cls,参数1,参数2 …) 这样的方式)
# __new__创建的实例,就是init中self的空间地址,也是类的实例对应的空间地址。
#__new__的作用主要有两个,一个是补充init无法实现的功能,另外一个是实现函数的单例模式

#单例模式
class Baby:
    __instance = None
    def __new__(cls, *args, **kwargs):
        if cls.__instance is None:
            cls.__instance = super().__new__(cls)
        return cls.__instance
    def __init__(self,cloth,pants):
        self.cloth = cloth
        self.pants = pants
b1 = Baby('红毛衣','绿皮裤')
print(b1.cloth)
b2 = Baby('白衬衫','黑豹纹')
print(b1.cloth)
print(b2.cloth)

#__str__和__repr__ 方法
# 在打印一个对象的时候 调用__str__方法
# 在%s拼接一个对象的时候 调用__str__方法
# 在str(一个对象)的时候 调用__str__方法
# 如果找不到__str__,就调用__repr__方法
# __repr__不仅是__str__的替代品,还有自己的功能
# 用%r进行字符串拼接 或者用repr(对象)的时候总是调用这个对象的__repr__方法

class clas:
    def __init__(self):
        self.student = []
    def append(self,name):
        self.student.append(name)
    def __repr__(self):
        return str(self.student)
    def __str__(self):
        return 'aaa'

py22 = clas()
py22.append('大壮')
print(py22) # aaa
print(str(py22)) # aaa
print('我们py22班 %s'%py22) # 我们py22班 aaa
print('我们py22班 %r'%py22) # 我们py22班 [大壮]
print(repr(py22))  # 我们py22班 [大壮]

相关文章

  • 20 类相关

    1.类指针:子类找父类,实例找类都是通过自身携带的类指针去寻找。 2.Python3中所有的类都继承于Object...

  • Fragment FragmentManager Fragmen

    Fragment相关类的关系及说明 UML类图 相关类说明 HostCallbacks:FragmentActiv...

  • 使用IDEA分析类的关系

    2017/3/20 | 周一 | 雨 今天在分析线程池的相关类的时候,偶然发现了IDEA类图分析的功能,用起来非常...

  • 癌症分子亚型的聚类

    通过查看基于表达丰度进行癌症分子亚型聚类的文献中相关的部分,并进行学习,将相关方法应用于George的数据。 20...

  • Kotlin学习(七): 类和继承、接口与实现

    本文是学习Kotlin的类和继承相关,嵌套类相关,接口相关。 类 Kotlin的类的声明与Java一样,使用cla...

  • 日期相关类

    Date类 java中用于描述日期的类。Date内部维护着一个long值,这个值表示的是1970-01-01 00...

  • GPUImage相关类

    GPUImage滤镜相关类 图像处理 Handle Image 视觉效果 Visual Effect 混合模式 B...

  • 日期相关类

  • 反射相关类

    1.获取Class类型的对象 Class类封装一个对象和接口运行时的状态,当装载类时,Class类型的对象自动创建...

  • 日期相关类

    1.Date类 A. 构造方法Date(); 根据当前系统时间创建日期对象Date(long time); 根...

网友评论

      本文标题:20 类相关

      本文链接:https://www.haomeiwen.com/subject/szsmwktx.html