HuaPu在学:Python基础知识—PyCharm版【私有化 & 继承 &多态 & 组合 & 运算符重载】


前言

`
“花圃记录学习日常”。刚开始走上Python之路,以下都是入门基础内容的一些要点笔记。


一、私有属性和方法

私有属性和方法

私有属性与私有方法实际上是实现封装的部分。
python中对于类成员没有严格的访问控制。
首先我们约定双下划线开头的属性或者方法是私有的,其他的是公有的、
其次类的内部可以访问私有属性或者方法,但是外部不能直接访问,注意是可以访问不是不能,通过 实例对象_类名__.私有属性或者方法 的形式。

class Person:
    def __init__(self,name,age):
        self.name=name
        self.__age=age  #声明属性私有
        pass
    def __work(self):   #声明方法私有
        print("well done!")
        pass
    pass

P=Person("HuaPu",18)
print(P.name,P._Person__age)  #调用私有属性的形式
P._Person__work()             #调用私有方法
输出结果:
HuaPu 18
well done!

@property装饰器

@property可以将一个方法的调用方式转换成属性的调用。实质上该装饰器可以方便我们的getter和setter(其他语言常见),方便我们在实例对象中的调用。

面向对象的三大特征

封装:

封装的另外名字可以是隐藏,隐藏对象的属性和实现细节,只提供必要的方法。通过之前说的私有属性、方法的方式,实现封装。

继承:

让子类具有父类的特性,,提高代码的重用性。从设计上是一种”增量式的进化“,原来父类有的子类也可以用,子类还可及增加新功能。

多态:

多态是一个方法对于不同的对象来说会产生不同的行为。

二、继承

语法格式

python中是支持多继承的,我们可以这么理解实际上对于之前我们学习的定义类,后面是没有(父类[,父类])这些形式的,但起始没有加任何()形式的类继承的默认是object类,比如我们可以定义初始化的__init__与创建对象__new__,这些方法实际上都来自object类。
class 类名(父类[,父类])

代码如下(示例):

class Person:
    def __init__(self,name,age):
        self.name=name
        self.__age=age  #声明属性私有
        pass
    def say(self):
        print("well done!")
        pass
    pass
class Student(Person):
    def __init__(self,name,age,score):
        Person.__init__(self,name,age)
        self.score=score
        pass
    def say_1(self):
        print("Good!")
    pass

H=Student("HuaPu",18,100)
print(H.name)
print(H.score)
H.say()
H.say_1()
print(H._Person__age)
print(H.age)
输出结果:
Traceback (most recent call last):
  File "D:/Python/mypy01/01.py", line 66, in <module>
    print(H.age)
AttributeError: 'Student' object has no attribute 'age'
HuaPu
100
well done!
Good!
18

上面的错误来自于,我们将父类中的age进行了私有化,事实上子类确实继承了这一属性,但是注意并不意味着继承了我就可以使用,依然是父类中的私有,调用依然需要固定的格式。

上面的Person.init(self,name,age)实际是子类继承父类时需要声明的继承父类的构造函数__init__,必须进行,不然解释器不会去调用。

【多重继承是支持的,但是会搞得特别复杂,尽量避免使用】

object根类及其他

查看类的继承层次关系mro()
方法解析顺序,广度搜索。打印层次结构。
产看对象属性dir()
重写__str__()方法
用于返回一个对于”对象的描述“。可以真么去理解,str输出的就是我们创建类的属性信息,也就是一个描述,那么我们默认是返回一个固定的object格式的信息,那么如果我们想让他返回想要的描述,就需要在类的内部自己去定义str()的重写方法。

代码如下(示例):

class Person:
    def __init__(self,name,age):
        self.name=name
        self.__age=age  #声明属性私有
        pass
    def say(self):
        print("well done!")
        pass
    pass
class Student(Person):
    def __init__(self,name,age,score):
        Person.__init__(self,name,age)
        self.score=score
        pass
    def say_1(self):
        print("Good!")
    pass
H=Person("HuaPu",18)
print(H)

输出结果:
<__main__.Person object at 0x0000019893A2DE48>
class Person:
    def __init__(self,name,age):
        self.name=name
        self.__age=age  #声明属性私有
        pass
    def say(self):
        print("well done!")
        pass
    def __str__(self):
        return "一个重新描述"
    pass
class Student(Person):
    def __init__(self,name,age,score):
        Person.__init__(self,name,age)
        self.score=score
        pass
    def say_1(self):
        print("Good!")
    pass
H=Person("HuaPu",18)
print(H)
输出结果:
一个重新描述

super()继承父类定义当我们子类继承父类的时候。我们知道,我们去创建一个子类的实例对象,那么我直接让创建好的实例对象去调用父类中有的方法是可以的,但我们在定义子类的过程中,我们如果要用到父类中的方法去实现子类方法,或者其他的地方要用到父类中的方法,那么很简单就用super()进行声明。【super().方法名()】

三、多态

多态实际上是同一个方法对于不同对象的一个使用,比如人这个大类之下,有中国人 英国人等, 定义一个方法 那么中国人用筷子去吃饭,英国人用刀叉,这就是不同对象的同一个方法调用去产生不同行为。

class Man():
    def eat(self):
        print("饿了")
        pass
    pass
class Chinese(Man):
    def eat(self):
        print("用筷子吃饭")
        pass
    pass
class English(Man):
    def eat(self):
        print("用刀叉吃饭")
        pass
    pass

def Eat(m):
    if isinstance(m,Man):
        m.eat()
        pass
    else:
        print("饱了")
        pass
    pass

Eat(Chinese())
输出结果:
用筷子吃饭

四、组合

首先组合与继承都是考虑代码复用的问题没有人说组合完全可以取代继承,但这种说法是极端的。那么一般我们这么使用:
is–a 比如 :狗是动物,这里就用继承
has–a 比如 : 电脑有CPU,这里就用组合的关系

class MobilePhone:
    def __init__(self,cpu,screen):
        self.cpu=cpu
        self.screen=screen
        pass
    pass
class Cpu:
    def calculate(self):
        print("计算")
        pass
    pass
class Screen:
    def show(self):
        print("亮度")
        pass
    pass

c1=Cpu()
s1=Screen()
m1=MobilePhone(c1,s1)
m1.cpu.calculate()
m1.screen.show()
输出结果:
计算
亮度

五、运算符的重载

这里其实可以简单的这么理解,比如我们常用的运算符“+*/……”等,实际上完全就是对象方法的调用,比如对于“+”来书,我们实际上是定义的__add__()这么一个方法,那么既然是方法,那么我们就可以在某一类中去重新加载这个方法的内容,在调用的时候我们就可实现重载功能。

六、深拷贝(deepcopy)与浅拷贝(copy)

深拷贝与浅拷贝实际上属于拷贝内容的问题,我们知道在内存里,变量在栈中,对象在堆中,那么当我去创建了一个对象之后,我对它进行浅拷贝,【当然这里注意,我们要导入copy模块】copy.copy(),浅拷贝进行完之后我们实际上是建立了一个新的对象,然后新的对象内部所包含的小对象也就是组成对象的地址,是完整的给了刚才新创建的对象。反观,深拷贝copy.deepcopy()是将原来的所有对象都复制下来去重新创建。
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值