Python面向对象oop编程(二)

简介: Python面向对象oop编程(二)

Hello,大家好,我是你们的老朋友景天,上一章我们聊到了python的面相对象编程的语法,以及一些面相对象的基本操作,今天我们继续深入探讨下面向对象的其他一些常用方法和规范

1.如何在类外访问私有成员

class Plane():
    # 公有成员
    captian = "赵沈阳"
    
    # 私有成员
    __air_sister = "3名空姐"
    
    # 公有绑定方法
    def fly(self):
        print("飞机要非要平流层,才能减少震动",self.__air_sister)
        
    # 私有绑定方法
    def __age(self):
        print("空姐年龄保密")
        
    # 公有无参方法
    def fly2():
        print("航天飞机飞到天空层,翱翔太空")
    
    # 私有无参方法
    def __earn():
        print("机长的收入保密")
        
    def pub_get1(self):
        print(self.__air_sister)
        self.__age()
        
    def pub_get2():
        print(Plane.__air_sister)
        Plane.__earn()

#实例化对象
obj = Plane()

方法一.访问私有成员 (不推荐) 使用改名方法,_类名+私有属性名

#python私有化,其实是: 采取了改名策略 =>  _类名 + __air_sister
#print(obj.__air_sister)
print(obj._Plane__air_sister)
print(Plane.__dict__)

{'__module__': '__main__', 'captian': '赵沈阳', 
'_Plane__air_sister': '3名空姐', 
'fly': <function Plane.fly at 0x7f2774616158>, '_Plane__age': <function Plane.__age at 0x7f27746161e0>, 'fly2': <function Plane.fly2 at 0x7f2774616268>, '_Plane__earn': <function Plane.__earn at 0x7f27746162f0>, '__dict__': <attribute '__dict__' of 'Plane' objects>, '__weakref__': <attribute '__weakref__' of 'Plane' objects>, '__doc__': None}


方法二.访问私有成员 (使用类中的公有方法,间接访问私有成员,包括调用私有属性和私有方法) (推荐)

obj = Plane()
obj.pub_get1()
Plane.pub_get2()

2.使用类对象删除相应的成员

1.对象可以访问类中的公有成员,但是无权修改或者删除该类中的成员

2.对象在访问成员时,优先访问该对象自己的成员,如果没有在访问类的,类如果也没有直接报错;

使用对象删除类的属性,方法,报错

#删除对象成员属性,但可以删除对象自己添加,修改的属性,方法

obj.captian = "赵世超"
del obj.captian
print(obj.captian)


#删除对象成员方法

obj.basketball = lambda : print("我的私人飞机可以在天上打篮球")
print(obj.__dict__)
obj.basketball()
del obj.basketball
print(obj.__dict__)
#obj.basketball() error

#删除类中成员属性 要通过类来删除

del Plane.captian
print(Plane.__dict__)
#Plane.captian
#print(obj.captian) error

#删除类中成员方法,删除类成员方法 不能加括号

del Plane.fly2
#Plane.fly2() error

#注意: 对象无法调无参方法!! 返回来,类可以调用对象的绑定方法么? 可以!!

Plane.fly(obj)

#类调用有参方法,要把类对象传进去

要删除私有的属性,方法。要在类内里面删除

3.构造方法

(1)init 构造方法 也就是初始化方法

所有编程语言都有构造方法

触发时机:实例化对象,初始化的时候触发
功能:为对象添加成员
参数:参数不固定,至少一个self参数
返回值:无

一般添加成员方法都是在类外,构造方法可以在创建对象的同时给对象创建成员

(2) 基本语法,至少加一个参数,本对象

class MyClass():
    def __init__(self):
        print("构造方法被触发 ... ")
        self.color = "屎黄色"
        
#实例化对象
obj = MyClass()
print(obj.__dict__)
print(obj.color)

如果定义了构造方法,则实例化对象的时候,该方法就会被调用。执行该方法的代码,可以为对象添加成员属性。只是给对象添加成员,并没有给类添加成员

只要创建对象,构造方法就被自动调用。 不是手动调用的

可以看到test对象被自动添加了color成员,并且__init__方法里面的代码也被自动执行

现在构造函数是把所有创建的对象都添加了color:蓝色 这个属性,并不是我们想要的结果。

此时就需要让构造函数带多个参数。创建对象时,可以带上参数,这样每个对象 都可以按传参不同而成员不同

(3) 带有多个参数的构造方法

class MyClass():
    def __init__(self,color):
        self.color = color

# 实例化对象
obj1 = MyClass("狗屎绿")
print(obj1.color)
obj2 = MyClass("粉嫩红")
print(obj2.color)

设置成员属性时,self.设置的成员属性名 = 传参传进来的值

这样就给对象添加了成员

这样,针对不同对象,就可以通过传参赋予不同的属性值

(3)类可以是一个,对象可以是多个,创造的对象彼此是独立的,可以给构造函数带多个参数,分别赋予不同的值;

class Children():
    def __init__(self,name,skin):
        self.name = name
        self.skin = skin
    
    def cry(self):
        print("小孩一下生久哇哇哇的哭")
    
    def la(self):
        print("小孩一下生久拉粑粑")
        
    def __eat(self):
        print("小孩一下生就要吃奶奶..")
    
        #这种成员方法,通过self.参数名 调用对象属性,创建对象的时候可通过类传参,对象调用的时候,通过对象传参,不用手动传参
    def info(self):
        print("小孩的名字:{},小孩的肤色{}".format(self.name,self.skin))
    
  #这种成员方法,直接调用参数名 对象调用该成员方法的时候,需要手动传参    。可以覆盖构造函数在创建对象时的值
    def info2(self,name,skin):
        print("小孩的名字:{},小孩的肤色{}".format(name,skin))

#实例化对象

afanda = Children("阿凡达","深蓝色")
afanda.cry()
afanda.info()

haoke = Children("绿巨人","绿色的")
haoke.la()
haoke.info()

wangbaoqiang = Children("王宝强","亮绿色")
wangbaoqiang.info()
# wangbaoqiang.__eat() error
wangbaoqiang.info2("张保张","黄色")

构造函数除了self外有几个参数,创建对象的时候,就必须带几个参数,不能少也不能多。否则创建对象失败

不能少参数

也不能多

成员方法带参数时,调用成员方法应该带参数

当成员方法里面是通过self.属性名 时,是通过对象来传参,调用函数时,传的参不会传进去

成员方法

调用:

当成员方法直接通过变量名来调用,调用时传参,会把创建对象时的参数覆盖


#这种成员方法,通过变量名调用参数。此时的参数是成员方法的形参,不是类或对象的成员属性

对象调用的时候,需要手动传参,会把创建对象时的参数覆盖。 但是这样调用比较麻烦,应该让对象来操作一切

4.继承

一个类除了自身所拥有的属性方法之外,还获取了另外一个类的成员属性和方法 是一种继承关系

被继承的类叫做父类(基类,超类),继承的类叫做子类(衍生类)

在python中所有类都继承object这个父类

继承: (1) 单继承 (2) 多继承

子类继承父类所有的属性和方法

节省了代码量

不由任意内置类型派生的类,称之为经典类

class 类名:

代码

新式类:

class 类名(object):

代码

Python面向对象的继承指的是多个类之间的从属关系,即子类默认继承父类所有的属性和方法

如果一个类不去写继承哪个类,默认继承的是object, object类是顶级类或基类。其他子类叫派生类

1.单继承

(1) 子父继承之后,子类可以调用父类的公有成员

class Human(object):
    eye = "黑色的"
    
    def jump(self):
        print("古代人类都能上树")
    
    def beat_animal(self):
        print("古代人类都会打猎")

    def __makefire(self):
        print("古代人类会生火")
        

class Man(Human):
    pass
    
obj = Man()
obj.jump()

(2) 子父继承之后,子类不能调用父类的私有成员

class Woman(Human):
    def pub_func(self):
        self.__makefire()
    
obj2 = Woman()
# obj2.__makefire()  不行
# obj2.pub_func()    不行

(3) 子父继承之后,子类可以重写父类的同名公有方法和属性

class Children(Human):
    def beat_animal(self):
        print("小孩天生只会打豆豆,不会打猎")
        
obj3 = Children()
obj3.beat_animal()

2.多继承

多继承就是一个类同时继承了多个父类

当一个类继承多个父类的时候,默认使用第一个父类的同名属性和方法

(1) 基本语法

class Father():
    property = "风流倜傥,才华横溢,玉树临风,才高八斗,学富五车,英姿洒窗"
    def f_hobby(self):
        print("吃喝嫖赌抽,坑蒙拐骗偷,抽烟喝酒烫头")
    
class Mother():
    property = "倾国倾城,貌美如花,沉鱼落雁,闭月羞花,婀娜多姿,前凸后翘"
    def m_hobby(self):
        print("蹦野迪,社会摇,打麻将,网红勾引小鲜肉")
        
class Daughter(Father,Mother):
    pass
    
obj = Daughter()
print(obj.property)
obj.m_hobby()

#当一个类继承多个父类的时候,默认使用第一个父类的同名属性和方法。按继承括号里面的先后顺序,谁在前先调用谁的

(2) 多继承的成员调用

class Father():
    property = "风流倜傥,才华横溢,玉树临风,才高八斗,学富五车,英姿洒窗"
    def f_hobby():
        print("吃喝嫖赌抽,坑蒙拐骗偷,抽烟喝酒烫头")
    
class Mother():
    property = "倾国倾城,貌美如花,沉鱼落雁,闭月羞花,婀娜多姿,前凸后翘"
    def m_hobby(self):
        print(self.property)
        print("蹦野迪,社会摇,打麻将,网红勾引小鲜肉")




super()调用父类方法:

语法一:super(当前类名, self).函数()

语法二:super().函数()

(1)super本身是一个类 super()是一个对象 传子类对象  用于调用父类的绑定方法
(2)super() 只应用在绑定方法中,默认自动传递self对象 (前提:super所在作用域存在self)
(3)super用途: 解决复杂的多继承调用顺序    
使用super()可以自动查找父类。调用的顺序遵循类.mro()方法返回的的列表顺序。比较适合单继承


class Son(Father,Mother):
    property = "打游戏,吃小零食"
    
    def m_hobby(self):
        print("son中m_hobby方法")
    
    
    # 用类调用成员
    def skill1(self):
        Father.f_hobby()
        print(Mother.property)
        
    # 用对象调用成员
    """self按照顺序找: 对象本身 => 类 => 父类 对应的成员 """
    def skill2(self):
        print(self.property)
        self.m_hobby()
        
    # 用super调用成员
    """super()只调用父类的相关成员,顺带传递对象参数"""
    def skill3(self):
        print(super())
        print(super().property)
        super().m_hobby()
        

obj2 = Son()
# obj2.skill1()

通过类调用指定类下的成员属性,类名.属性名

obj2.property = "喜欢看lol,dnf,wow,跑跑卡丁车,ddo,霸王大陆,澄海3c"
# obj2.skill2()

obj2.skill3()

即便在子类中存在同名方法或属性,也不调用。只调用父类方法和属性

super() 只应用在绑定方法中,默认自动传递self对象 (前提:super所在作用域存在self)

如果调用非绑定方法,会报错

f_hobby()方法非绑定方法

通过super()调用报错

通过super调用父类方法,是把子类对象传过去,执行,如果方法中调用对象成员属性,则调用的是子类成员属性

(3).菱形继承 (钻石继承) super深度理解

“”"

Human

Man Woman

Children

“”"

四个类中都有同名方法,该怎么调

class MyClass():
    pass

class Human():
    pty = 1
    def feelT(self):
        print("古代人类,天热了,光腚1")
        print(self.pty)
        print("古代人类,天冷了,穿寿衣2")
    
class Man(Human):
    # pty = 2
    def feelT(self):
        print("男人,天热了,光膀子3")
        print(super(),"<==2==>")
        super().feelT()
        print("男人,天冷了,光腚4")
    
class Woman(Human):
    # pty = 3
    def feelT(self):
        print("女人,天热了,脱毛5")
        print(super(),"<==3==>")
        super().feelT()
        print("女人,天冷了,穿貂6")

class Children(Man,Woman):
    # pty = 4
    def feelT(self):
        print("小孩,天热了,光腚7")
        print(super(),"<==1==>")
        super().feelT()
        print("小孩,天冷了,多喝热水8")


# ### super的深层理解
obj = Children()
obj.feelT()
# 73512648

super调用顺序

#mro: 方法解析顺序 (c3算法计算的)

#语法: 类.mro() => 列表

m :method

r :resolution

o :order

super 会自动根据mro列表返回出来的顺序关系,依次调用

super作用:专门用于解决复杂的多继承调用顺序关系;依照mro返回的列表顺序,依次调用;

super调用的顺序:会按照c3算法的广度优先原则进行调用

super传参:会默认在调用方法时,传递该对象参数;

lst = Children.mro()
print(lst)

[
<class '__main__.Children'>, 
<class '__main__.Man'>, 
<class '__main__.Woman'>,
<class '__main__.Human'>, 
<class 'object'>
]

根据 类.mro方法返回的列表顺序,来调用。遇到super().feelT()暂停,查找下一个调用

当不确定调用顺序时,可以打印下这个列表,来确认

# ### issubclass与isinstance
# issubclass 判断类的子父关系(应用在类与类之间) 第一个参数是子,第二个参数是父  是父子关系返回True,非父子关系返回False
"""只要在一条继承链上满足关系即可"""
res = issubclass(Children,Man)
res = issubclass(Children,Human)
res = issubclass(Children,MyClass)
# 如果元组当中有一个父类满足,即返回真
res = issubclass(Children,  (Man,Human,MyClass)  )
print(res)

# isinstance 判断对象的类型  (应用在类与对象之间)  第一个参数是对象,第二个参数是类
"""只要在一条继承链上满足关系即可"""
res = isinstance(obj,Children)
res = isinstance(obj,Human)
res = isinstance(obj,MyClass)
# 如果元组当中有一个类满足,即返回真
res = isinstance(obj,  (Man,Human,MyClass)  )
print(res)

#该对象只要是该类,或者该类的子类创建的,返回的都是True

(4).多继的承弊端

多继承的弊端会造成菱形继承这种情况,找不清调用顺序

super对象按照mro列表的顺序依次调用,解决菱形继承存在的问题

经典类:深度优先 (python2.x)

新式类:广度优先 (python3.x)

写多继承时,尽量避免造成不同类相同方法名的情况,提高代码质量 高内聚,低耦合

高内聚:一个模块只完成一个任务,专一性高

低耦合:模块与模块之间可以彼此独立不冲突,方便移植复用.


相关文章
|
8天前
|
机器学习/深度学习 人工智能 TensorFlow
人工智能浪潮下的自我修养:从Python编程入门到深度学习实践
【10月更文挑战第39天】本文旨在为初学者提供一条清晰的道路,从Python基础语法的掌握到深度学习领域的探索。我们将通过简明扼要的语言和实际代码示例,引导读者逐步构建起对人工智能技术的理解和应用能力。文章不仅涵盖Python编程的基础,还将深入探讨深度学习的核心概念、工具和实战技巧,帮助读者在AI的浪潮中找到自己的位置。
|
8天前
|
机器学习/深度学习 数据挖掘 Python
Python编程入门——从零开始构建你的第一个程序
【10月更文挑战第39天】本文将带你走进Python的世界,通过简单易懂的语言和实际的代码示例,让你快速掌握Python的基础语法。无论你是编程新手还是想学习新语言的老手,这篇文章都能为你提供有价值的信息。我们将从变量、数据类型、控制结构等基本概念入手,逐步过渡到函数、模块等高级特性,最后通过一个综合示例来巩固所学知识。让我们一起开启Python编程之旅吧!
|
8天前
|
存储 Python
Python编程入门:打造你的第一个程序
【10月更文挑战第39天】在数字时代的浪潮中,掌握编程技能如同掌握了一门新时代的语言。本文将引导你步入Python编程的奇妙世界,从零基础出发,一步步构建你的第一个程序。我们将探索编程的基本概念,通过简单示例理解变量、数据类型和控制结构,最终实现一个简单的猜数字游戏。这不仅是一段代码的旅程,更是逻辑思维和问题解决能力的锻炼之旅。准备好了吗?让我们开始吧!
|
2天前
|
存储 人工智能 数据挖掘
Python编程入门:打造你的第一个程序
本文旨在为初学者提供Python编程的初步指导,通过介绍Python语言的基础概念、开发环境的搭建以及一个简单的代码示例,帮助读者快速入门。文章将引导你理解编程思维,学会如何编写、运行和调试Python代码,从而开启编程之旅。
22 2
|
2天前
|
存储 数据挖掘 开发者
Python编程入门:从零到英雄
在这篇文章中,我们将一起踏上Python编程的奇幻之旅。无论你是编程新手,还是希望拓展技能的开发者,本教程都将为你提供一条清晰的道路,引导你从基础语法走向实际应用。通过精心设计的代码示例和练习,你将学会如何用Python解决实际问题,并准备好迎接更复杂的编程挑战。让我们一起探索这个强大的语言,开启你的编程生涯吧!
|
3天前
|
存储 Python
Python编程入门:理解基础语法与编写简单程序
本文旨在为初学者提供一个关于如何开始使用Python编程语言的指南。我们将从安装Python环境开始,逐步介绍变量、数据类型、控制结构、函数和模块等基本概念。通过实例演示和练习,读者将学会如何编写简单的Python程序,并了解如何解决常见的编程问题。文章最后将提供一些资源,以供进一步学习和实践。
11 1
|
10天前
|
设计模式 算法 搜索推荐
Python编程中的设计模式:优雅解决复杂问题的钥匙####
本文将探讨Python编程中几种核心设计模式的应用实例与优势,不涉及具体代码示例,而是聚焦于每种模式背后的设计理念、适用场景及其如何促进代码的可维护性和扩展性。通过理解这些设计模式,开发者可以更加高效地构建软件系统,实现代码复用,提升项目质量。 ####
|
6天前
|
存储 网络协议 IDE
从零起步学习Python编程
从零起步学习Python编程
|
9天前
|
机器学习/深度学习 存储 算法
探索Python编程:从基础到高级应用
【10月更文挑战第38天】本文旨在引导读者从Python的基础知识出发,逐渐深入到高级编程概念。通过简明的语言和实际代码示例,我们将一起探索这门语言的魅力和潜力,理解它如何帮助解决现实问题,并启发我们思考编程在现代社会中的作用和意义。
|
10天前
|
机器学习/深度学习 数据挖掘 开发者
Python编程入门:理解基础语法与编写第一个程序
【10月更文挑战第37天】本文旨在为初学者提供Python编程的初步了解,通过简明的语言和直观的例子,引导读者掌握Python的基础语法,并完成一个简单的程序。我们将从变量、数据类型到控制结构,逐步展开讲解,确保即使是编程新手也能轻松跟上。文章末尾附有完整代码示例,供读者参考和实践。
下一篇
无影云桌面