文章目录
前言
`
“花圃记录学习日常”。刚开始走上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()是将原来的所有对象都复制下来去重新创建。