基础 | Python面向对象一文详解

简介: 基础 | Python面向对象一文详解

本期导读

大家好,我是欧K。

本期为大家带来Python基础系列面向对象部分的内容,包括类和对象的理解、实例的创建与调用,以及子类继承和多态等等,希望对你有所帮助。



在介绍python面向对象编程之前,先来了解几个术语

  • : 用来描述具有相同的属性和方法的对象的集合,它定义了该集合中每个对象所共有的属性和方法。
  • 数据成员:类变量或者实例变量, 用于处理类及其实例对象的相关的数据。
  • 类变量:类变量在整个实例化的对象中是公用的,类变量定义在类中且在函数体之外,类变量通常不作为实例变量使用。
  • 实例变量:在类的声明中,属性是用变量来表示的,这种变量就称为实例变量,是在类声明的内部但是在类的其他成员方法之外声明的。
  • 方法:类中定义的函数。
  • 实例化:创建一个类的实例,类的具体对象。
  • 对象:通过类定义的数据结构实例,对象包括数据成员(类变量和实例变量)和方法。
  • 继承:即一个派生类继承基类的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。
  • 多态:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖,也称为方法的重写。


一个简单的实例

# 创建一个学生类
class Student:
    course_count = 4  # 类变量
    # 定义学生属性(构造函数)
    def __init__(self, name, number):
        self.name = name # 实例变量
        self.number = number # 实例变量
    # 定义方法
    def show(self):
        print(f'姓名: {self.name},学号: {self.number}')
# 实例化
stu1 = Student('当打之年','001')
stu1.show()
print(f'共 {stu1.course_count} 门课程')
# 姓名: 当打之年,学号: 001
# 共 4 门课程
stu2 = Student('欧K','002')
stu2.show()
print(f'共 {stu2.course_count} 门课程')
# 姓名: 欧K,学号: 002
# 共 4 门课程


1. 类


1.1 创建


语法格式

class ClassName:
   '''变量'''
   '''方法'''
   pass

class 是关键字,表示类。例如 class Student 即创建了一个 Student 类。


1.2 数据成员


数据成员包括:变量方法


1.2.1 变量:


类变量:定义在类中且在函数体之外,在实例化对象中是公有的。

course_count = 4  # 类变量

实例变量:在类的内部,但是在类的其他成员方法之外声明实例化对象中是私有的

def __init__(self, name, number):
    self.name = name # 实例变量
    self.number = number # 实例变量

本例是通过构造函数来声明,类变量和实例变量的区别很大,访问方式也也不一样。


1.2.2 方法:


类中定义的函数:

# 定义方法
def show(self):
    print(f'姓名: {self.name},学号: {self.number}')

初始化时的构造函数也是一种方法。


提示:


在对象的方法里面都有一个self参数, 比如__init__(self), show(self)。 这里的self是指对象本身而非类本身。

构造方法__init__(self,....):在生成对象时调用,可以用来进行一些初始化操作,不需要显示去调用,系统会默认去执行。构造方法支持重载,如果用户自己没有重新定义构造方法,系统就自动执行默认的构造方法。


1.4 私有/公有


类里面的私有属性和私有方法以双下划线__开头。私有属性或方法不能在类的外部被使用或直接访问,公有属性和公有方法可以在类的外部被使用或直接访问


def __init__(self, name, number, score):
    self.name = name # 实例变量
    self.number = number # 实例变量
    self.__score = score # 私有变量
# 实例化
stu1 = Student('当打之年','001',90)
print(stu1.name) # 当打之年
print(stu1.__score) # AttributeError: 'Student' object has no attribute '__score'


2. 对象/实例


2.1 创建(类的实例化) 实例化两个Student对象:

# 实例化
stu1 = Student('当打之年','001')
stu2 = Student('欧K','002')

实例化需要传入相应的参数。


2.2 调用


调用一般指类方法的调用

# 实例化
stu1 = Student('当打之年','001')
stu1.show()
print(f'共 {stu1.course_count} 门课程')
# 姓名: 当打之年,学号: 001
# 共 4 门课程
stu2 = Student('欧K','002')
stu2.show()
print(f'共 {stu2.course_count} 门课程')
# 姓名: 欧K,学号: 002
# 共 4 门课程

直接通过实例对象调用即可。print语句中使用了f-string格式化,具体用法可参考下面这篇文章(点击跳转)技巧 | 5000字超全解析Python三种格式化输出方式【% / format / f-string】


2.2.1 @classmethod(类方法)


@classmethod将函数定义为类方法,函数可通过类和实例调用声明前:

def get_course_count(self):
    print(f'共 {self.course_count} 门课程')
# 实例化
stu1 = Student('当打之年','001')
stu1.get_course_count() # 共 4 门课程
Student.get_course_count() # TypeError: get_course_count() missing 1 required positional argument: 'self'

声明后:

@classmethod
def get_course_count(cls):
    print(f'共 {self.course_count} 门课程')
# 实例化
stu1 = Student('当打之年','001')
stu1.get_course_count() # 共 4 门课程
Student.get_course_count() # 共 4 门课程

这里的cls和self相似,是惯用写法,均可用其他字符代替。


2.2.2 @staticmethod(静态函数) 


@staticmethod 将函数定义为静态函数,类和实例都可以访问,但是静态函数无法访问类变量:

@staticmethod
def student_info(a,b,c):
    print(f'姓名: {a},学号: {b},共 {c} 门课程') # 姓名: 当打之年,学号: 001,共 4 门课程
    print(f'姓名: {a},学号: {b},共 {course_count} 门课程') # 错误
# 实例化
stu1 = Student('当打之年','001')
stu1.student_info('当打之年','001',4) # 姓名: 当打之年,学号: 001,共 4 门课程

course_count为类变量,直接访问会报错,此外静态函数参数个数没有要求,可有可无。


2.2.3 @property(伪装)


@property 将函数伪装成属性:

@property
def get_student_info(self):
    print(f'姓名: {self.name},学号: {self.number},共 {self.course_count} 门课程')
# 实例化
stu1 = Student('当打之年','001')
stu1.get_student_info() # TypeError: 'NoneType' object is not callable
stu1.get_student_info # 姓名: 当打之年,学号: 001,共 4 门课程

此时的get_student_info函数被伪装成实例属性(类似变量)而不在是函数,所以通过函数调用的方式会报错,可直接通过属性调用。


3. 继承


面向对象的编程带来的最大好处之一就是代码的复用,实现这种的方法之一是通过继承。先定义一个基类(父类),再按通过class子类名(父类名)来创建子类,这样子类就可以从父类那里获得其已有的属性与方法。


3.1 子类


语法格式(单继承、多继承)

# 单继承
class ChildClassName(FatherClassName):
   '''变量'''
   '''方法'''
   pass
# 多继承
class ChildClassName(FatherClassName1,FatherClassName2,...):
   '''变量'''
   '''方法'''
   pass
父类:大学学生类,子类:某专业学生类
# 创建一个大学学生类
class CollegeStudent:
    print('我是父类')
    # 定义学生属性(构造函数)
    def __init__(self, name, number):
        self.name = name # 实例变量
        self.number = number # 实例变量
    # 定义方法
    def show(self):
        print(f'姓名: {self.name},学号: {self.number}')
# 创建某专业学生子类
class Student(CollegeStudent):
    print('我是子类')
    pass
# 实例化
stu1 = Student('当打之年','001')
stu1.show() # 姓名: 当打之年,学号: 001

3.2 派生


派生就是子类在继承父类的基础上衍生出新的属性或者方法。即子类中有,父类中没有;或子类定义与父类重名的东西。子类也叫派生类。


3.2.1 增加属性:

# 创建某专业学生子类
class Student(CollegeStudent):
    def __init__(self, name, number, score):
        CollegeStudent.__init__(self, name, number)
        self.score = score # 实例变量
    # 定义方法
    def show_score(self):
        print(f'姓名: {self.name},学号: {self.number},成绩: {self.score}')
# 实例化
stu1 = Student('当打之年','001',99)
stu1.show() # 姓名: 当打之年,学号: 001
stu1.show_score() # 姓名: 当打之年,学号: 001,成绩: 99

stu1.show()是调用父类方法,stu1.show_score()是调用子类新增的方法。


3.2.2 方法重写:

# 创建某专业学生子类
class Student(CollegeStudent):
    def __init__(self, name, number, score):
        CollegeStudent.__init__(self, name, number)
        self.score = score # 实例变量
    # 重写方法
    def show(self):
        print(f'姓名: {self.name},学号: {self.number},成绩: {self.score}')
# 实例化
stu1 = Student('当打之年','001',99)
stu1.show() # 姓名: 当打之年,学号: 001,成绩: 99

父类和子类中都有show()方法,子类中show()方法是对父类该方法的重写(重定义)


3.2.3 super()关键字:


如果父类方法被重写,但是还需要调用父类方法的话,可以使用super()关键字。

# 创建某专业学生子类
class Student(CollegeStudent):
    def __init__(self, name, number, score):
        CollegeStudent.__init__(self, name, number)
        self.score = score # 实例变量
    # 重写方法
    def show(self):
        super().show()
        '''其他代码'''
# 实例化
stu1 = Student('当打之年','001',99)
stu1.show() # 姓名: 当打之年,学号: 001


4. 多态


Python中的变量是弱类型的,对于弱类型的语言来说,变量并没有声明类型,因此,同一个变量完全可以在不同的时间引用不同的对象,当同一个变量在调用不同的方法时,完全可能呈现多种行为(具体呈现出哪种行为由该变量所引用的对象决定),即多种形态


4.1 方法多态


创建两个类:学生类、教师类

# 创建学生类
class Student:
    def __init__(self, name, number, score):
        self.name = name # 实例变量
        self.number = number # 实例变量
        self.score = score # 私有变量
    def show(self):
        print(f'学生姓名: {self.name},学号: {self.number},成绩: {self.score}')
# 创建教师类
class Teacher:
    def __init__(self, name, number):
        self.name = name # 实例变量
        self.number = number # 实例变量
    def show(self):
        print(f'教师姓名: {self.name},工号: {self.number}')
# 实例化学生对象
stu1 = Student('当打之年','001',99)
stu1.show() # 学生姓名: 当打之年,学号: 001,成绩: 99
# 实例化教师对象
tec1 = Teacher('Python','t101')
tec1.show() # 教师姓名: Python,工号: t101

两个类都具有show()方法,但是实现的功能不一样,即同一种方法不同的功能。


4.2 运算符多态

加法多态

def add(data1, data2):
    return data1 + data2
print(add(3, 5)) # 8
print(add('Python ', '当打之年')) # Python 当打之年

上述定义的加法运算符我们不用关心两个参数data1data2体是什么类型,只要是支持加法运算的对象就可以,即可以是多种形态的对象


4.3 运算符重载


以加法、减法重载为例

# 运算符类
class Operate:
    def __init__(self, data):
        self.data = data
    # 内置魔法函数
    def __repr__(self): # 消除两边的尖括号
        return f'Operate({self.data})'
    # 制定self + other规则
    def __add__(self, other):
        a = self.data + other.data
        return Operate(a)
    # 制定self - other规则
    def __sub__(self, other):
        a = self.data - other.data
        return Operate(a)
r1 = Operate(100)
r2 = Operate(300)
r3 = r1 + r2 # Operate(400)
print(r3)
r4 = r3 - r2 # Operate(100)

所有重载方法的名称前后都有两个下划线字符,以便把同类中定义的变量名区别开来。


5. 总结

两个核心:类、对象

三大特征 :封装、继承、多态

重点注意继承和多态,旨在提高代码的复用性以及灵活性。


END


以上就是本期为大家整理的全部内容了,赶快练习起来吧,喜欢的朋友可以点赞、点在看也可以分享到朋友圈让更多人知道哦

相关文章
|
2月前
|
Java 程序员 C++
Python 面向对象详解!
本文详细介绍了Python中的面向对象编程(OOP),包括类、对象、继承、封装、多态和抽象等核心概念。通过具体示例,解释了如何使用类定义对象的属性和方法,以及如何通过继承实现代码重用。文章还探讨了封装和多态的重要性,并介绍了私有属性和抽象类的使用方法。最后,总结了OOP的四大支柱:封装、抽象、继承和多态,强调了这些概念在Python编程中的应用。适合Java程序员扩展Python编程知识。
79 2
|
14天前
|
关系型数据库 开发者 Python
Python编程中的面向对象设计原则####
在本文中,我们将探讨Python编程中的面向对象设计原则。面向对象编程(OOP)是一种通过使用“对象”和“类”的概念来组织代码的方法。我们将介绍SOLID原则,包括单一职责原则、开放/封闭原则、里氏替换原则、接口隔离原则和依赖倒置原则。这些原则有助于提高代码的可读性、可维护性和可扩展性。 ####
|
4月前
|
Python
你真的会面向对象吗!解密Python“魔术方法”
你真的会面向对象吗!解密Python“魔术方法”
45 0
|
2月前
|
Python
Python面向对象(2)
【10月更文挑战第14天】
Python面向对象(2)
|
2月前
|
设计模式 程序员 C语言
Python面向对象
【10月更文挑战第13天】
Python面向对象
|
6月前
|
Python
Python进阶第一篇(Python的面向对象)
Python进阶第一篇(Python的面向对象)
|
7月前
|
存储 算法 安全
Python编程实验六:面向对象应用
Python编程实验六:面向对象应用
115 1
|
3月前
|
前端开发 Python
Python编程的面向对象有哪些(二)
Python编程的面向对象(二)—类的多态
27 7
|
3月前
|
IDE Java 开发工具
Python类与面向对象
Python类与面向对象
|
7月前
|
人工智能 自然语言处理 开发者
Python基础教程——面向对象
Python基础教程——面向对象