Python面向对象编程ya【进阶】

132 阅读11分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情 前言 上上篇我们讲解了Python面向对象编程的基础知识,《Python基础篇:面向对象怎样炼成的》这篇我们继续来讨论面向对象编程相关的内容。

目录 前言 可见性和属性装饰器 动态属性 静态方法和类方法 继承和多态 总结 可见性和属性装饰器 在很多面向对象编程语言中,对象的属性通常会被设置为私有(private)或受保护(protected)的成员,简单的说就是不允许直接访问这些属性;对象的方法通常都是公开的(public),因为公开的方法是对象能够接受的消息,也是对象暴 def age(self): return self.__age

stu = Student('王大锤', 20) print(stu.name, stu.age) # 王大锤 20 stu.name = '' print(stu.name) # 无名氏

stu.age = 30 # AttributeError: can't set attribute

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 在实际项目开发中,我们并不经常使用私有属性,属性装饰器的使用也比较少,所以上面的知识点大家简单了解一下就可以了。

动态属性 Python是一门动态语言,维基百科对动态语言的解释是:“在运行时可以改变其结构的语言,例如新的函数、对象、甚至代码可以被引进,已有的函数可以被删除或是其他结构上的变化。动态语言非常灵活,目前流行的Python和JavaScript都是动态语言,除此之外如PHP、Ruby等也都属于动态语言,而C、C++等语言则不属于动态语言”。

在Python中,我们可以动态为对象添加属性,这是Python作为动态类型语言的一项特权,代码如下所示。需要提醒大家的是,对象的方法其实本质上也是对象的属性,如果给对象发送一个无法接收的消息,引发的异常仍然是AttributeError。

class Student:

3 4 5 6 7 8 9 10 如果不希望在使用对象时动态的为对象添加属性,可以使用Python的__slots__魔法。对于Student类来说,可以在类中指定__slots__ = ('name', 'age'),这样Student类的对象只能有name和age属性,如果想动态添加其他属性将会引发异常,代码如下所示。

class Student: slots = ('name', 'age')

stu = Student('王大锤', 20)

AttributeError: 'Student' object has no attribute 'sex'

stu.sex = '男' 1 2 3 4 5 6 7 8 9 10 11 静态方法和类方法 之前我们在类中定义的方法都是对象方法,换句话说这些方法都是对象可以接收的消息。除了对象方法之外,类中还可以有静态方法和类方法,这两类方法是发给类的消息,二者并没有实质性的区别。在面向对象的世界里,一切皆为对象,我们定义的每一个类其实也是一个对象,而静态方法和类方法就是发送给类对象的消息。那么,什么样的消息会直接发送给类对象呢?

举一个例子,定义一个三角形类,通过传入三条边的长度来构造三角形,并提供计算周长和面积的方法。计算周长和面积肯定是三角形对象的方法,这一点毫无疑问。但是在创建三角形对象时,传入的三条边长未必能构造出三角形,为此我们可以先写一个方法来验证给定的三条边长是否可以构成三角形,这种方法很显然就不是对象方法,因为在调用这个方法时三角形对象还没有创建出来。我们可以把这类方法设计为静态方法或类方法,也就是说这类方法不是发送给三角形对象的消息,而是发送给三角形类的消息,代码如下所示。

class Triangle(object): """三角形类"""

def init(self, a, b, c): """初始化方法""" self.a = a self.b = b self.c = c

@staticmethod def is_valid(a, b, c): """判断三条边长能否构成三角形(静态方法)""" return a + b > c and b + c > a and a + c > b self.c

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 上面的代码使用staticmethod装饰器声明了is_valid方法是Triangle类的静态方法,如果要声明类方法,可以使用classmethod装饰器。可以直接使用类名.方法名的方式来调用静态方法和类方法,二者的区别在于,类方法的第一个参数是类对象本身,而静态方法则没有这个参数。简单的总结一下,对象方法、类方法、静态方法都可以通过类名.方法名的方式来调用,区别在于方法的第一个参数到底是普通对象还是类对象,还是没有接受消息的对象。静态方法通常也可以直接写成一个独立的函数,因为它并没有跟特定的对象绑定。

继承和多态 面向对象的编程语言支持在已有类的基础上创建新类,从而减少重复代码的编写。提供继承信息的类叫做父类(超类、基类),得到继承信息的类叫做子类(派生类、衍生类)。例如,我们定义一个学生类和一个老师类,我们会发现他们有大量的重复代码,而这些重复代码都是老师和学生作为人的公共属性和行为,所以在这种情况下,我们应该先定义人类,再通过继承,从人类派生出老师类和学生类,代码如下所示。

class Person: """人类""" def init(self, name, age): self.name = name self.age = age
def eat(self): print(f'{self.name}正在吃饭.')
def sleep(self): print(f'{self.name}正在睡觉.')

class Student(Person): """学生类"""

def init(self, name, age): # super(Student, self).init(name, age) super().init(name, age)

def study(self, course_name): print(f'{self.name}正在学习{course_name}.')

class Teacher(Person): """老师类"""

def init(self, name, age, title): # super(Teacher, self).init(name, age) super().init(name, age) self.title = title

def teach(self, course_name):
    print(f'{self.name}{self.title}正在讲授{course_name}.')

stu1 = Student('白元芳', 21) stu2 = Student('狄仁杰', 22) teacher = Teacher('武则天', 35, '副教授') stu1.eat() stu2.sleep() teacher.teach('Python程序设计') stu1.study('Python程序设计')

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 继承的语法是在定义类的时候,在类名后的圆括号中指定当前类的父类。如果定义一个类的时候没有指定它的父类是谁,那么默认的父类是object类。object类是Python中的顶级类,这也就意味着所有的类都是它的子类,要么直接继承它,要么间接继承它。Python语言允许多重继承,也就是说一个类可以有一个或多个父类,关于多重继承的问题我们在后面会有更为详细的讨论。在子类的初始化方法中,我们可以通过super().init()来调用父类初始化方法,super函数是Python内置函数中专门为获取当前对象的父类对象而设计的。从上面的代码可以看出,子类除了可以通过继承得到父类提供的属性和方法外,还可以定义自己特有的属性和方法,所以子类比父类拥有的更多的能力。在实际开发中,我们经常会用子类对象去替换掉一个父类对象,这是面向对象编程中一个常见的行为,也叫做“里氏替换原则”(Liskov Substitution Principle)。

子类继承父类的方法后,还可以对方法进行重写(重新实现该方法),不同的子类可以对父类的同一个方法给出不同的实现版本,这样的方法在程序运行时就会表现出多态行为(调用相同的方法,做了不同的事情)。多态是面向对象编程中最精髓的部分,当然也是对初学者来说最难以理解和灵活运用的部分,我们会在之后专门的例子来讲解多态这个知识点。

总结 Python是动态语言,Python中的对象可以动态的添加属性。在面向对象的世界中,一切皆为对象,我们定义的类也是对象,所以类也可以接收消息,对应的方法是类方法或静态方法。通过继承,我们可以从已有的类创建新类,实现对已有类代码的复用。

文章已被收录至官方知识档案 Python入门技能树进阶任务Python问答139146 人正在系统学习中

源码/资料/实战项目,备注:C站

微信名片

五包辣条! 关注

19

24

0

专栏目录 面向对象编程进阶 weixin_44049823的博客 210 子类通过 this (...)去调用本类的其他构造器,本类其他构造器会通过super去手动调用父类的构造器,最终还是会调用父类构造器的。 this(…) super(…) 都只能放在构造器的第一行,所以二者不能共存在同一个构造器中。否则会造成调用两次父类构造器的情况。 Day9 :面向对象进阶 最新发布 Sumarua的博客 1364 实际上,我们写在类中的方法并不需要都是对象方法,例如我们定义一个“三角形”类,通过传入三条边长来构造三角形,并提供计算周长和面积的方法,但是传入的三条边长未必能构造出三角形对象,因此我们可以先写一个方法来验证三条边长是否可以构成三角形,这个方法很显然就不是对象方法,因为在调用这个方法时三角形对象尚未创建出来(因为都不知道三条边能不能构成三角形),所以这个方法是属于三角形类而并不属于三角形对象的。复用现有的代码不仅可以减少开发的工作量,也有利于代码的管理和维护,这是我们在日常工作中都会使用到的技术手段。... 3.26学习笔记 weixin_55974491的博客 38 3.26学习笔记 class Student: def init(self, name, gender='男', age=18, tel=''): self.name = name self.gender = gender self.age = age self.tel = tel def repr(self): return str(self.dict) stu1 = Student python属于什么类型的语言 热门推荐 yatum_2014的博客 2万+ 编译型和解释型 编译型和解释型各有利弊,随着设计技术与硬件不断发展,编译型与解释型两种方式的界限正在不断变得模糊。 类型 编译型:一次把所有代码转换为机器语言 解释型: 脚本语言 执行过程 编译器(Compiler):一个负责翻译的程序来对我们的源代码进行转换,生成相对应的可执行代码 可执行代码:编译之后就会直接生成一个可执行文... python属于低级语言还是高级语言,【单选题】Python语言属于 A. 机器语言 B. 汇编语言 C. 高级语言 D. 科学计算语言... weixin_39962125的博客 6437 【单选题】Python语言属于A. 机器语言 B. 汇编语言 C. 高级语言 D. 科学计算语言更多相关问题[判断题] 玻璃电极敏感膜外壁有微量锈时,可用浓酸浸泡消除。[判断题] 天平的灵敏度越高越好。[判断题] 对锅炉给水经常要监督的项目是硬度、溶解氧、pH值、铜、铁,目的是防止热力设备及系统腐蚀、结垢。[判断题] 饱和氯化钾电极在储存时应将上端的注入口塞紧,使用时才能打开。[判断题] 标准溶液... python是什么语言的脚本-Python代码是什么语言 weixin_37988176的博客 276 Python代码是一种计算机程序设计语言,是一种动态的、面向对象的脚本语言,最初是用来编写自动化脚本的,随着版本的不断更新和语言新功能的添加,越来越多被用于独立的、大型项目的开发。Python代码是:python的中文名称是蟒蛇。Python是一种计算机程序设计语言。是一种动态的、面向对象的脚本语言,最初是用来编写自动化脚本的,随着版本的不断更新和语言新功能的添加,越来越多被用于独立的、大型项目的... python语言是什么语言 590