程序笔记   发布时间:2022-07-12  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Python——什么是面向对象?类的定义、self和继承详解大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

创作不易࿰c;来了的客官点点关注࿰c;收藏࿰c;订阅一键三连❤ὡc; 

往期系列

Python——函数大全及使用方法! lambda?global?

Python——流程控制࿰c;pass?break?conTinue?这些你弄清楚了吗?

目录

常见的三种编程范式

函数式编程

面向过程编程

面向对象编程 (OOP-Object Oriented ProgrAMMing)

面向过程VS面向对象

面向对象的基本概念

类(class申明)

类:用来描述具有相同属性和方法的对象的集合࿰c;分为基类、子类。

对象

类的实例化

类的定义与使用

类空间和实例空间

类的基本特点

类的定义与使用

__init__方法

__new__方法

__init__与__new__总结

小练习:创建类࿰c;实现计算学生的总成绩与平均分

类的self方法

类-self

练习:用面向对象实现斐波那契数列

类的继承

面向对象的好处

继承

使用继承的好处

python的多态

练习:利用类自定义异常类


 

常见的三种编程范式

函数式编程

• 函数可以作为参数传递、修改࿰c;或作为返回值

• 函数内不修改外部变量的状态

面向过程编程

• 根据操作数据的语句块来实现功能。

def login(username,passwd):

    if username == "root" and passwd == "123456":

        return True

    else:

        return false

面向对象编程 (OOP-Object Oriented ProgrAMMing)

• 把数据和功能结合起来࿰c;用称为对象的东西包裹起来组织程序的方法。

class Logincheck():

    # 登陆数据

    username = "root"

    passwd = "123456"

    # 登录功能

    def login(self,username,passwd):

        if username == "root" and passwd == "123456":

            return True

        else:

            return false

面向过程VS面向对象

• 面向过程是一件事"该怎么做", 着重于做什么。

面向过程 = 分析问题 + 逻辑

优点:性能比面向对象高࿰c;因为类调用时需要实例化࿰c;开销比较大࿰c;比较消耗资源;比如单片机、嵌入式开发、 Linux/Unix等一般采用面向过程开发࿰c;性能是最重要的因素。

缺点:没有面向对象易维护、易复用、易扩展

面向对象是一件事"该让谁来做"c;着重于谁去做

优点:易维护、易复用、易扩展࿰c;由于面向对象有封装、继承、多态性的特性࿰c;可以设计出低耦合的系统࿰c;使系统 更加灵活、更加易于维护

缺点:性能比面向过程低


面向对象的基本概念

• 对象:通过类定义的数据结构实例。

• 对象包括两个数据成员(类变量和实例变量)和方法。

• python一切皆对象࿰c;类是对象࿰c;实例也是对象

示例代码:

class Bus317(object):

    # 类属性

    line = "317"

    # 方法-->行为

    def run(self,flag):

        print("bus317 is run")

        if flag == 0:

            print("从农大到长华小区")

        else:

            print("从长华小区到农大")

实例化:创建了一个对象

bus01 = Bus317()

bus02 = Bus317()

类(class申明)

类:用来描述具有相同属性和方法的对象的集合࿰c;分为基类、子类。

什么是类?

生活例子:车可以理解为一个类࿰c;特征:有车轮、车牌࿰c;方法:会跑

基类/子类

车-->基类;摩托车࿰c;大卡车-->子类

对象

实例:具体的某一个事务࿰c;某个类型实实在在的一个例子

类的实例化

通过类创建的一个具体的实例࿰c;类的具体对象;

类就是一个生产实例的工厂࿰c;类就是一个模型图

实例化

lg1 = Logincheck()

lg1就是一个对象࿰c;实例去干活

print(lg1.login("root1","21323"))


类的定义与使用

类空间和实例空间

创建类的时候就会创建类空间

实例化对象时就会生成实例空间࿰c;不同的实例有单独的空间

实例查找属性方法时࿰c;会现在实例空间查找࿰c;找不到就去类空间查找࿰c;类空间找不到就去父空间查找

eg:bus01.xx --> 查找xx属性

先在他自己的实例空间查找--找不到就去Bus317里找--再找不到再去object找--最后找不到就报错

类的基本特点

封装(Encapsulation)

  在类中对数据的赋值、内部调用对外部用户是透明的

  把一些功能的实现细节不对外暴露

  将数据和函数做了一层封装࿰c;封装成类࿰c;使用者不需要管具体实现的代码

• 继承(InheritancE)

  继承:即一个派生类(derived class)继承基类(base class)的字段和方法。

  目的:为实现代码的重用࿰c; 一个类可以派生出子类

  继承也允许把一个派生类的对象作为一个基类对象对待。

• 多态(Polymorphism)

  接口重用࿰c; 一个接口࿰c;多种实现(重写)

类的定义与使用

• 类名的规范

  一般首字母大写(大驼峰)

  Person, GoodsInfo

• 函数的命名

  由小写字母和下划线组成

  scan_book, drink

• 类的定义方式(关键字:class)

python2 => 经典类和新式类

python3 => 新式类

继承了object类的类都属于新式类࿰c;没有继承的属于经典类

class A():

    pass

class B:

    pass

class C(object):

    pass

python3中以上三种定义没有区别࿰c;默认会继承object类

class Bus317(object):

    # 类属性

    line = "317"

    # 方法-->行为

    def run(self,flag):

        print("bus317 is run")

        if flag == 0:

            print("从农大到长华小区")

        else:

            print("从长华小区到农大")

#实例化:创建了一个对象

bus01 = Bus317()

bus02 = Bus317()



#打印类和实例的内存:类和实例化都有单独的命名空间

print(id(Bus317),id(bus01),id(bus02))



#查看对象的属性或方法

print(dir(bus01))

print(bus01.linE)

bus01.run(0)

bus02.run(1)



#直接用类访问属性

print(Bus317.linE)

__init__方法

实例化对象的构造方法,实例化对象的时候会自动调用__init__方法

用来初始化属性

__new__方法

创建实例化࿰c;一般情况下不需要重写࿰c;静态方法

class Bus317(object):

    # 类属性

    # line-->公共属性

    line = "317"

    def __init__(self,pro):

        print("this is __init__")

        self.pro1 = pro

    # cls接收到的参数就是当前类(Bus317)

    def __new__(cls, *args, **kwargs):

        print("this is new method")

        return "new"

        # return object.__new__(cls)

        # 返回父类object.__new__方法通过当前类创建的对象

    # *args和 ** kwargs主要用于函数定义。你可以将不定数量的参数传递给一个函数。

    # 这里的不定的意思是: 预先并不知道, 函数使用者会传递多少个参数给你, 所以在这个场景下使用这两个关键字。

    def run(self,flag):

        print("bus317 is run")

        if flag == 0:

            print("从农大到长华小区")

        else:

            print("从长华小区到农大")

# 创建实例

bus01 = Bus317("benci","chao")

bus02 = Bus317("futian")

print(bus01)

# print(dir(bus01))

# print(bus01.pro1,bus02.pro1)

# 查看类空间有什么东西

# print(Bus317.__Dict__)

# 查看实例空间有什么内容

# print(bus01.__Dict__)

__init__与__new__总结

__init__是对创建好的实例࿰c;进行初始化工作的方法

__new__是创建实例的方法

1.__new__方法必须传入一个参数(cls)࿰c;代表当前类

2.__new__必须返回一个实例化的对象

3、__init__的self就表示__new__返回的实例࿰c;__init__对这个实例进行初始化工作

4、子类没有__new__࿰c;会去找父类的__new__

5、新式类才有__new__

6、如果实例化对象和本身class不一致࿰c;__init__不会执行

小练习:创建类࿰c;实现计算学生的总成绩与平均分

创建一个学生类

• 类名:student

• 属性:姓名࿰c;年龄࿰c;学校࿰c;成绩(字典)

{'yuwen':100, 'suxue':100, 'yinyu':100}

• 方法:求总分、求平均值

class student(object):

    school = "hunau"

    def __init__(self,name,age,scores):

        # 初始化函数࿰c;self-->实例本身

        self.name = name

        self.age = age

        self.school = student.school # 使用类属性

        self.scores = scores



    def sum(self):

        # sum1 = 0

        # for i in self.scores.values():

        #     sum1 += i

        # return sum1

        # 方法二

        return sum(self.scores.values())

    def avg(self):

        # avg1 = self.sum()/len(self.scores)

        # return avg1

        # 方法二

        return self.sum()/len(self.scores)





lzc = student("lzc", 20,{"math":100,"Chinese":90})

lzw = student("lzw", 20,{"math":98,"Chinese":92})

llf = student("llf", 20,{"math":97,"Chinese":91})

print(lzc.sum())

print(lzc.avg())

类的self方法

类-self

类的实例方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称

在调用这个方法的时候你不为这个参数赋值࿰c;Python会提供这个值

这个特别的变量指对象本身࿰c;按照惯例它的名称是self

class A:

    NAME = "sc"

    age = 4



    def info(self,seX):

        print(f"我是:{self.namE},今年{self.agE}岁࿰c;性别{sex}")

        print(self)

        print(id(self))

    def info2(chao):

        print(f"this is {Chao}")



#self 表示实例本身

a = A()

print(id(a))

a.info("man")

print("***")

A.info(a,"man") # 实际上运行

#输出结果:

1889166028752

我是:sc,今年4岁࿰c;性别man

<__main__.A object at 0x000001B7DB11EFD0>

1889166028752

self 不必非写成self࿰c;self的名字不是强制规定的(可以理解为不一定要命名为self)

最好还是尊重约定俗成的习惯࿰c;使用self

b = A()

b.info2()

#输出结果:

this is <__main__.A object at 0x00000278DEEEEFD0>

方法中可以不传入self࿰c;如果不写的话就不能使用对象调用

实例调用方法的时候࿰c;默认就会把当前的实例传给self࿰c;不需要手动传入

示例:

class Parent:

    def pprt(self):

        print(self)

 

class Child(Parent):

    def cprt(self):

        print(self)

       

c = Child()

c.cprt()

c.pprt()

#输出结果:

<__main__.Child object at 0x00000278DEEEEFA0>

<__main__.Child object at 0x00000278DEEEEFA0>

练习:用面向对象实现斐波那契数列

用类实现斐波那契数列的运算(编写自定义迭代器)

斐波那契数列: 0 1 1 2 3 5

码如下

class Fib_list:

    def __init__(self):

        self.before = 0

        self.now = 1

 

    def __iter__(self):

        return self

 

    def __next__(self):

        result = self.now

        self.before,self.now=self.now,self.before+self.now

        return result

 

a = Fib_list()

 

print([next(a) for i in range(11)])

类的继承

面向对象的好处

面向对象的编程带来的主要好处之一是代码的重用c;实现这种重用的方法之一是通过继承机制

继承完全可以理解成类之间的类型和子类型关系。

• 可以节省很多的代码࿰c;不需要写࿰c;直接使用

• 衍生出不同的子类࿰c;大部分代码一样࿰c;部分代码不一样

继承

• 继承父类的属性和方法

• 对象属性查找

先在实例空间查找࿰c;没有就去类空间

再没有就去父类空间找࿰c;层层往上递归查找

class Animal():

    species = "Animal"

    count = 0

    def __init__(self):

        self.name = "animal"

        Animal.count += 1

        print("初始化animal......")



    def breath(self):

        print("i can breath")



    def eat(self):

        print("i can eat")



# 继承Animal类

class Person(Animal):

    species = "Person" #重写父类属性



class Dog(Animal):

    species = "Dog"



    def __init__(self):  #重写父类的__init__

        print("i am dog")



    def eat(self): #重写父类的eat()

        print("dog is eatTing......")



class Pig(Animal):

    count = 0 #重写父类属性



    def __init__(self):  #重写父类__init__

        self.name = "pig"

        Pig.count += 1

        print("初始化Pig......")

        super().__init__() #去执行父类的__init__,子类访问父类属性的方法属性



print(Animal.count)

# 输出结果

0



# 实例化Animal

animal = Animal()

print(Animal.count,animal.count)

# 输出结果

初始化animal......

1 1



# 实例化Person

person = Person()

print(person.species,person.count,Person.count)

#输出结果

初始化animal......

Person 2 2



# 实例化Dog

dog = Dog()

print(dog.count)

print("*"*5)

# 输出结果

i am dog

2



# 实例化Pig

pig = Pig()

print(pig.count,pig.Name)

# 输出结果

初始化Pig......

初始化animal......

1 animal



# 类与实例的关系

print("类与实例的关系".center(30,"*"))

print(type(dog))

print(isinstance(dog,Dog), isinstance(dog, Animal))

# 输出结果

***********类与实例的关系************

<class '__main__.Dog'>

True True

使用继承的好处

增加了代码的利用率c;如果需要给Pig/Person同时增加新的功能时࿰c;只需要在Animal中添加即可

便于更新迭代c;如果你的父类方法的功能不能满足你的需求࿰c;你可以在子类重写你父类的方法父类里的方法

python的多态

python不支持多态࿰c;语法上的多态࿰c;不需要额外实现多态代码

python里处处都是多态,python是一个多态类型语言࿰c;本身就实现了多态࿰c;崇尚鸭子类型

在鸭子类型中࿰c;关注的不是对象的类型本身࿰c;而是它是如何使用的。

多态的好处

• 增加了程序的灵活性

• 以不变应万变࿰c;不论对象千变万化࿰c;使用者都是同一种形式去调用࿰c;如func(animal)

• 增加了程序额可扩展性

• 通过继承animal类创建了一个新的类࿰c;使用者无需更改自己的代码࿰c;还是用func(animal)去调用

• 多态:同一种事物的多种形态࿰c;动物分为人类࿰c;猪类(在定义角度)

• 多态性:一种调用方式࿰c;不同的执行效果(多态性)

• 实现接口重用

练习:利用类自定义异常类

自定义异常类

• 自定义异常能让异常更精准

• 自定义异常类:当list内元素长度超过10的时候抛出异常

• 自定义异常类:消息小于8时抛出异常

 方法一

class List_Error(Exception):

    pass

lst1 = [1,2,3]

if not 8<len(lst1)<10:

    raise List_Error("列表长度小于8或超出10")

else:

    print("No Problem")

方法二:

class List_Error(Exception):# 注:继承Exception的基类

    def __init__(self,lst,messagE):

        self.lst = lst

        self.message = message



    def __str__(self):

        str1 = "list is " + str(self.lst)

        str1 = str1 +"n" + self.message

        return str1



try:

    lst = [1,2,3,4,5,6]

    if not 8 < len(lst) < 10:

        raise List_Error(lst,"列表长度小于8或超出10!")



except List_Error as e:

    print("listError error:",E)

创作不易࿰c;客官点个赞吧!评论一下!一起加油❤ὡc;   

大佬总结

以上是大佬教程为你收集整理的Python——什么是面向对象?类的定义、self和继承详解全部内容,希望文章能够帮你解决Python——什么是面向对象?类的定义、self和继承详解所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。