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)

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

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

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


相关文章
|
6月前
|
机器学习/深度学习 存储 设计模式
Python 高级编程与实战:深入理解性能优化与调试技巧
本文深入探讨了Python的性能优化与调试技巧,涵盖profiling、caching、Cython等优化工具,以及pdb、logging、assert等调试方法。通过实战项目,如优化斐波那契数列计算和调试Web应用,帮助读者掌握这些技术,提升编程效率。附有进一步学习资源,助力读者深入学习。
|
3月前
|
Python
Python编程基石:整型、浮点、字符串与布尔值完全解读
本文介绍了Python中的四种基本数据类型:整型(int)、浮点型(float)、字符串(str)和布尔型(bool)。整型表示无大小限制的整数,支持各类运算;浮点型遵循IEEE 754标准,需注意精度问题;字符串是不可变序列,支持多种操作与方法;布尔型仅有True和False两个值,可与其他类型转换。掌握这些类型及其转换规则是Python编程的基础。
195 33
|
2月前
|
数据采集 分布式计算 大数据
不会Python,还敢说搞大数据?一文带你入门大数据编程的“硬核”真相
不会Python,还敢说搞大数据?一文带你入门大数据编程的“硬核”真相
69 1
|
3月前
|
设计模式 安全 Python
Python编程精进:正则表达式
正则表达式是一种强大的文本处理工具,用于搜索、匹配和提取模式。本文介绍了正则表达式的语法基础,如`\d`、`\w`等符号,并通过实例展示其在匹配电子邮件、验证电话号码、处理日期格式等场景中的应用。同时,文章提醒用户注意性能、编码、安全性等问题,避免常见错误,如特殊字符转义不当、量词使用错误等。掌握正则表达式能显著提升文本处理效率,但需结合实际需求谨慎设计模式。
129 2
|
4月前
|
数据采集 安全 BI
用Python编程基础提升工作效率
一、文件处理整明白了,少加两小时班 (敲暖气管子)领导让整理100个Excel表?手都干抽筋儿了?Python就跟铲雪车似的,哗哗给你整利索!
112 11
|
6月前
|
人工智能 Java 数据安全/隐私保护
[oeasy]python081_ai编程最佳实践_ai辅助编程_提出要求_解决问题
本文介绍了如何利用AI辅助编程解决实际问题,以猫屎咖啡的购买为例,逐步实现将购买斤数换算成人民币金额的功能。文章强调了与AI协作时的三个要点:1) 去除无关信息,聚焦目标;2) 将复杂任务拆解为小步骤,逐步完成;3) 巩固已有成果后再推进。最终代码实现了输入验证、单位转换和价格计算,并保留两位小数。总结指出,在AI时代,人类负责明确目标、拆分任务和确认结果,AI则负责生成代码、解释含义和提供优化建议,编程不会被取代,而是会更广泛地融入各领域。
177 28
|
6月前
|
机器学习/深度学习 数据可视化 TensorFlow
Python 高级编程与实战:深入理解数据科学与机器学习
本文深入探讨了Python在数据科学与机器学习中的应用,介绍了pandas、numpy、matplotlib等数据科学工具,以及scikit-learn、tensorflow、keras等机器学习库。通过实战项目,如数据可视化和鸢尾花数据集分类,帮助读者掌握这些技术。最后提供了进一步学习资源,助力提升Python编程技能。
|
6月前
|
设计模式 机器学习/深度学习 前端开发
Python 高级编程与实战:深入理解设计模式与软件架构
本文深入探讨了Python中的设计模式与软件架构,涵盖单例、工厂、观察者模式及MVC、微服务架构,并通过实战项目如插件系统和Web应用帮助读者掌握这些技术。文章提供了代码示例,便于理解和实践。最后推荐了进一步学习的资源,助力提升Python编程技能。
|
6月前
|
Python
[oeasy]python074_ai辅助编程_水果程序_fruits_apple_banana_加法_python之禅
本文回顾了从模块导入变量和函数的方法,并通过一个求和程序实例,讲解了Python中输入处理、类型转换及异常处理的应用。重点分析了“明了胜于晦涩”(Explicit is better than implicit)的Python之禅理念,强调代码应清晰明确。最后总结了加法运算程序的实现过程,并预告后续内容将深入探讨变量类型的隐式与显式问题。附有相关资源链接供进一步学习。
80 4
|
6月前
|
数据采集 搜索推荐 C语言
Python 高级编程与实战:深入理解性能优化与调试技巧
本文深入探讨了Python的性能优化和调试技巧,涵盖使用内置函数、列表推导式、生成器、`cProfile`、`numpy`等优化手段,以及`print`、`assert`、`pdb`和`logging`等调试方法。通过实战项目如优化排序算法和日志记录的Web爬虫,帮助你编写高效稳定的Python程序。

推荐镜像

更多