首页 > 其他分享 >动静态方法、多继承与派生

动静态方法、多继承与派生

时间:2022-11-03 18:04:55浏览次数:52  
标签:静态方法 name 派生 继承 self 查找 print obj class

1.动静态方法

1.在类中的定义的函数有多种属性
"""
类名加括号会产生一个对象,对象用点函数名的方式不用传参因为func1会把gro当做参数传进去。类名点函数名需要传一个参数。
"""
class Group:
    s = 'from Group'

    def func1(self):
        print('from func1')


gro = Group()
gro.func1()  # from func1
Group.func1(11)  # from func1

"""
被@classmethod修饰的函数默认绑定给类,类会将自身当做第一个参数传入,所以用类调用此函数时不用传参。用对象调用也不用传参。
"""
class Group:
    s = 'from Group'

    def func1(self):
        print('from func1')

    @classmethod
    def func2(cls):
        print('from func2', cls)
        
gro = Group()
Group.func2()  # from func2 <class '__main__.Group'>  # 相当于func2(Group)
gro.func2()  # from func2 <class '__main__.Group'>       

"""
静态方法:被@staticmethod修饰的函数就是一个普普通通的函数,用类或者对象调用都需要手动传参
"""
class Group:
    s = 'from Group'

    def func1(self):
        print('from func1')

    @classmethod
    def func2(cls):
        print('from func2', cls)

    @staticmethod
    def func3(a):
        print('from func3', a)


gro = Group()
Group.func3('类调用也需要传参')  # from func3 类调用也需要传参
gro.func3('对象调用也需要传参')  # from func3 对象调用也需要传参

2.面向对象之继承的概念

"""
面向对象三大特性
	封装 继承 多态
1.三者中继承最为核心(实操最多 体验最强)
2.封装和多态略微抽象
"""
1.继承的含义:
    在现实生活中表示人与人之间资源的丛书关系。eg:儿子继承父亲
    在编程世界里表示类与类之间资源的从属关系
    
2.继承的目的:
    和现实生活中类似,编程中继承表示不同类之间资源丛书关系。比如类B继承类A,那么类B当中可以共享类A中的数据和功能
    
3.继承实操:
	3.1在定义类的时候类名后面可以加括号填写其他类名,表示继承其他类名
	3.2在python中支持多继承,括号内填写多个类名,用逗号隔开即可
class Student:
    name = 'max'

class Grade9(Student):
    pass

gra = Grade9()
print(gra.name)  # max
"""
1.继承其他类的类,我们称为子类、派生类
2.被继承的类,我们称之为父类
"""

3.继承的本质

"""
通过对象和类的概念引出继承的本质:
对象:数据与功能的结合体
类:多个对象相同数据和功能的结合体
父类:多个类(子类)相同数据和功能的结合体
类与父类本质都是为了节省代码
"""
继承本质应该分为两部分:
	抽象:将多个类相同的东西抽出去形成一个新的类
 	继承:将多个类继承刚刚抽取出来的新的类

4.对象名字的查找顺序

1.不继承情况下名字的查找顺序:
    1.1:当对象中有名字时,先从对象的名称空间中查找
class A1:
    name = 'max'

    def func(self):
        print('from func')

obj1 = A1()
obj1.name = 'jason'
print(obj1.__dict__)  # {'name': 'jason'}
print(obj1.name)  # jason

	1.2:当对象中没有名字时,去类中查找
class A1:
    name = 'max'

    def func(self):
        print('from func')

obj1 = A1()
print(obj1.__dict__)  # {}
print(obj1.name)  # max

	1.3:如果类中也没有,直接报错
class A1:
    age = 18

    def func(self):
        print('from func')

obj1 = A1()
print(obj1.name)  # 报错
 """
 对象名称空间>>>类(没有即报错)
 """

2.单继承情况下名字查找顺序:
	2.1当对象名称空间中有要找的名字时,直接去对象名称空间中查找  
class A1:
    name = 'max'

class B1(A1):
    name = 'jason'

class C1(B1):
    name = 'jerry'

obj1 = C1()
obj1.name = 'oscar'
print(obj1.name)  # oscar

	2.2当对象名称空间中没有时,去产生对象的类名称空间中查找
class A1:
    name = 'max'

class B1(A1):
    name = 'jason'

class C1(B1):
    name = 'jerry'

obj1 = C1()
print(obj1.name)  # jerry

	2.3当类名称空间中没有时,去父类名称空间中查找
class A1:
    name = 'max'

class B1(A1):
    pass

class C1(B1):
    pass

obj1 = C1()
print(obj1.name)  # max
"""
对象名称空间>>>产生对象的类名称空间>>>父类(没有即报错)
"""
class A1:  # 3.在B1类父类的名称空间中查找
    def func1(self):
        print('from A1 func1')

    def func2(self):
        print('from A1 func2')  # 4.找到func2(),首先打印'from A1 func2'
        self.func1()  # 5.self此时等于obj,此时找obj.func1()

class B1(A1):  # 2.在obj的类名称空间中查找,没有  # 6.obj的对象名称空间中没有,此事到类B1名称空间中查找
    def func1(self):
        print('from B1 func1')  # 7.打印'from B1 func1'

obj = B1()
obj.func2()  # 1.在obj对象名称空间中查找func2(),没有,对象名加括号会将对象名当做参数传递给函数
"""
对象点名字,一定是从对象名称空间中开始查找;看到self时要知道self指代的是谁,是谁就从哪个对象的名称空间中开始查找
"""

3.多继承情况下名字的查找顺序
	3.1多继承情况下名字的查找顺序:对象名称空间有时直接从对象名称空间中查找 
class A:
    name = 'from A'

class B:
    name = 'from B'

class C:
    name = 'from C'

class S(A, B, C):
    name = 'from S'

obj = S()
obj.name = 'obj名称空间中的name'
print(obj.name)  # obj名称空间中的name

	3.2对象名称空间没有时,从产生它的类名称空间的查找
class A:
    name = 'from A'

class B:
    name = 'from B'

class C:
    name = 'from C'

class S(A, B, C):
    name = 'from S'

obj = S()
print(obj.name)  # from S

	3.3类名称空间没有时直接从父类中查找(顺序从左往右依次查找)
class A:
    name = 'from A'

class B:
    name = 'from B'

class C:
    name = 'from C'

class S(A, B, C):
    pass

obj = S()
print(obj.name)  # from A

4.非菱形继承
class G:
    name = 'from G'


class A:
    name = 'from A'


class B:
    name = 'from B'


class C:
    name = 'from C'


class D(A):
    name = 'from D'


class E(B):
    name = 'from E'


class F(C):
    name = 'from F'


class S1(D, E, F):
    pass


obj = S1()
print(obj.name)
"""
非菱形继承查找顺序先从对象名称空间查找,再到类名称空间,再到父类名称空间,父类查找顺序为从左到右,每一个父类找到不能走位置
"""
也可以用print(s1.mro)方法来查看查找顺序
5.菱形继承
class G:
    name = 'from G'
    pass
class A(G):
    name = 'from A'
    pass
class B(G):
    name = 'from B'
    pass
class C(G):
    name = 'from C'
    pass
class D(A):
    name = 'from D'
    pass
class E(B):
    name = 'from E'
    pass
class F(C):
    name = 'from F'
    pass

class S1(D,E,F):
    pass
obj = S1()
print(obj.name)
"""
菱形查找顺序为先从对象你名称空间中查找,再到类名称空间,再到父类名称空间。父类名称空间查找顺序从左到右,走道菱形交汇点之前停止,直到所有的类都找完,再找交汇点的类。
"""

5.经典类与新式类

"""
经典类:不继承object或者其子类的类
新式类:继承object或者其子类的类
    在python2中有经典类和新式类
    在python3中只有新式类(所有类默认都继承object)
"""
class Student(object):pass
为了更好地兼容python2,以后我们在定义类的时候,如果没有其他明确的父类,也可以直接在括号内加上object

6.派生方法

1.子类基于父类做扩展:Student的父类为Person,说明在类Student中可以用到类Person中的名字,但是类Student还想扩展一个名字level,此时可以用到关键字super().__init__(父类中的名字),然后再扩展自己新增的名字
class Person:
    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender

class Student(Person):
    def __init__(self, name, age, gender, level):
        super().__init__(name, age, gender)
        self.level = level

stu1 = Student('max', 25, 'male', 3)
print(stu1.__dict__)  # {'name': 'max', 'age': 25, 'gender': 'male', 'level': 3}

class Teacher(Person):
    def __init__(self, name, age, gender, grade):
        super().__init__(name, age, gender)
        self.grade = grade

tea1 = Teacher('jerry', 30, 'male', 9)
print(tea1.__dict__)  # {'name': 'jerry', 'age': 30, 'gender': 'male', 'grade': 9}

2.通过super关键字扩展数据类型列表的属性,并且限制尾部追加功能
class Mylist(list):
    def append(self, values):
        if values == 'jason':
            print('jason不能尾部追加')
            return
        super().append(values)

obj = Mylist()
print(obj, type(obj))  # [] <class '__main__.Mylist'>
obj.append('max')
obj.append('jerry') 
obj.append('jason')  # jason不能尾部追加
print(obj)  # ['max', 'jerry']

标签:静态方法,name,派生,继承,self,查找,print,obj,class
From: https://www.cnblogs.com/zkz0206/p/16855333.html

相关文章

  • Python基础指面向对象:2、动静态方法
    面向对象一、动静态方法在类中定义的函数有多种特性1、直接在类中定义函数​ 再类中直接定义函数,默认绑定给对象,类调用时有几个参数就要传几个参数,对象调用时该函数......
  • Python基础之面向对象:3、继承与派生
    面向对象一、三大特征之继承python三大特征:封装、继承、多态三者中继承最为核心,实际应用对,感受较为直观封装和多态略微抽象1、继承的概念继承的含义:​......
  • 面向对象之继承
    动静态方法面向对象之继承理论继承基本操作对象查找名字的顺序(非常重要)继承本质基于继承的派生方法(重要)动静态方法1.绑定给对象的方法#类中定义的函数有多种......
  • 面向对象:继承、动静态方法
    目录一、动静态方法1类中直接定义函数2被@classmethod修饰的函数3静态函数被@staticmethod修饰的函数二、面向对象-继承1面向对象三大特性2继承的概念1.继承的......
  • 面向对象2、动静态方法、继承、名字查找顺序、经典类、新式类、派生方法
    目录今日内容概要今日内容详细动静态方法面向对象之继承的概念继承的本质名字的查找顺序经典类与新式类派生方法作业今日内容概要动静态方法面向对象之继承理论继承基......
  • 关于继承自stl容器的派生类
    我在一篇知乎上看到说继承后,由于stl的实现没有虚析构函数,所以会产生泄露。更有甚者说继承是UB。但是我在cppreference上看到如下内容:structsame:std::binary_function......
  • Java自定义排序:继承Comparable接口,重写compareTo方法(排序规则)
    importjava.util.Arrays;importjava.util.TreeMap;/***学习自定义排序:继承Comparable接口,重写compareTo方法(排序规则)。*TreeMap容器的Key是自动排序的,key为......
  • 【笔记14】Javascript - 继承
    【笔记14】Javascript-继承继承的概念不陌生,在原型、原型链那里,就知道一个对象能继承到原型很多属性和方法。各种继承的方法有优势有不足,看下继承发展史:继承传统形式:原型......
  • Demo54_关于继承_02_super与this
      子类代码://继承packagecom.oop.Jichen_3;//学生类继承学校类publicclassstudentextendsschool{publicstudent(){//本类的无参构造方法super();......
  • Semi-join使用条件,派生表优化 (3)—mysql基于规则优化(四十六)
    前面说了子查询里有no/any/all不能用limit,groupby,orderby等,他会被查询优化器优化掉,子查询可能会物化转成内连接semi-join查询,物化就是会吧子查询看做一个表,如果数据太大,超......