Python-8.面向对象程序设计
砂糖桑
Aug 12, 2022
Last edited: 2022-8-14
type
Post
status
Published
date
Aug 12, 2022
slug
python-8
summary
面向对象的思想在C++中已经涉及得很多了,所以在Python面向对象的学习中主要学习Python语言面向对象的一些特性,如类对象、实例对象、类属性、实例属性等,并进一步理解Python中“一切皆对象”。
tags
Python课堂笔记合集
category
Python
icon
password
Property
Aug 14, 2022 11:17 AM
面向对象不仅是一种语言特性,更是一种程序设计思想。在C++中已经研究了很多面向对象的思想了,所以这篇文章的学习中更注重的是”Python中的面向对象”。
面向对象的三大核心内容是封装、继承与多态。封装就是使用类,继承与多态也要使用类来实现。
类与封装
Python中定义一个类的方式是:
class ClassName: 属性 方法
使用类可以实例化很多个对象或实例:
instance_name=ClassName()两种对象与两种属性
两种对象
Python中一切皆对象——类其实也是对象。创建类其实就是创建了一个类对象,它由type类实例化而来:

使用类实例化的对象或实例也是对象,它是对应的类类型的对象,这点很好理解。

类对象只有一个,而使用类实例化的实例对象可以有很多个。
两种属性
Python中与类相关的有类对象与实例对象,对应的,类中的属性有类属性与实例属性。
类属性就是在类的公共部分定义的属性,类对象和实例对象都能访问到类属性;实例属性在方法(实例方法)中定义,前面使用self加以限定,表明这是一个实例属性:
class Student: amount=100 # 类属性 def __init__(self,name='Sato',age=18): self.name=name # 实例属性 self.age=age
为什么Python要分类属性和实例属性,而不像C++一样直接用一个属性?主要目的还是为了更好地模拟现实世界:类属性可以设置为一个群体的属性,如班里学生的数量;实例属性则设置为个体的属性,如学生的姓名、年龄等。
- 对于类对象和每个实例对象,类属性是公用的。改一个其他都会变。
# 通过类对象修改类属性,实例对象再访问类属性就会发生变化 std1=Student(name='Sato') print(std1.amount) # 输出100 Student.amount+=1 print(std1.amount) # 输出101
- 类对象访问不到实例属性,且对于不同的实例,实例属性不互通。
# 两个实例对应的实例属性不互通 std1=Student(name='Sato') std2=Student(name='Prexius') print(std1.name+' VS '+std2.name)
- 使用
实例对象.属性可以修改或添加实例属性——如果存在这个实例属性,那么就修改;如果不存在,那么就添加这个实例属性。需要注意如果实例属性和类属性重名,那么实例属性会覆盖掉类属性。只有删除这个实例属性才能恢复对类属性的访问。
在第一点中没有通过实例对象来修改实例属性正是因为这个原因:
std1=Student(name='Sato') std1.amount+=1 print(Student.amount) # 依然输出100 print(std1.amount) # 输出101
std1.amount相当于添加了一个名为amount的实例属性覆盖掉了原来的类属性,所以二者不再互通了。要验证通过实例对象也能修改类属性,需要使用类方法:
class Student: amount=100 # 类属性 def __init__(self,name='Sato',age=18): self.name=name # 实例属性 self.age=age @classmethod def add(cls): cls.amount += 1 std1=Student(name='Sato') std1.add() print(Student.amount) # 输出101 print(std1.amount) # 输出101
一切皆对象

Python中一切皆对象。如这些常用类型和类一样也是type的实例。
有这样一个很好的例子:(
__base__代表基类)class A:pass a = A() print(A.__bases__) # (<class 'object'>,) print(object.__bases__) # () print(type(a)) # <class '__main__.A'> print(type(A)) # <class 'type'> print(type(object)) # <class 'type'> print(type.__bases__) # (<class 'object'>,)
可以推出原型链和继承链:

结论是所有对象都是type的实例,所有对象都是继承于object的子类。
不太懂为什么,还需要继续研究。先记住这个结论吧。
三种方法
类中可以有三种:实例方法、类方法和静态方法。
实例方法
类中直接定义的方法就是实例方法,它有一个默认的形参self指向调用这方法的实例,类对象不能调用实例方法。
class Student: __amount = 100 # 类属性 def __init__(self, name='Sato', age=18): self.name = name # 实例属性 self.age = age def get_amount(self): # 实例方法 return self.__amount std = Student() print(std.get_amount()) # 实例对象调用实例方法 try: Student.get_amount() except: print("类对象不能调用实例方法")
类方法
类方法使用@classmethod修饰符加以限定,类方法有一个默认的形参cls,指向类对象本身。所以类对象和实例对象都可以调用类方法,实例方法主要使用类方法来修改类属性的值。
class Student: amount=100 # 类属性 def __init__(self,name='Sato',age=18): self.name=name # 实例属性 self.age=age @classmethod def add(cls): cls.amount += 1 std1=Student(name='Sato') std1.add() print(Student.amount) # 输出101 print(std1.amount) # 输出101
静态方法
静态方法没有cls,也没有self。它和类外面的函数的区别是它可以访问到类中的私有属性,但必须使用类名.类属性的方式。类对象和实例对象都可以调用。
class Student: __amount = 100 # 类属性 def __init__(self, name='Sato', age=18): self.name = name # 实例属性 self.age = age @staticmethod def get_amount(): return Student.__amount print(Student.get_amount()) std = Student() print(std.get_amount())
构造与析构
Python的构造函数是
__init__,析构函数是__del__。分别用于初始化对象时赋值和清除对象的空间。class Student: def __init__(self): print("执行了构造函数") def __del__(self): print("执行了析构函数") std = Student() # 执行了构造函数 del std # 执行了析构函数
此外还有一个
__new__方法,它的作用是创建并返回对象。与__init__相比,__new__完成的是初始化的工作,而__init__完成的是初始化后的赋值工作。继承与派生
继承
一个类的默认父类是object,可以通过__base__来验证。
所以说,前面定义Student类写完整应该如下:
class Student(object): pass
将父类放在括号里面就行了。
如果父类有构造函数,子类也有构造函数,那么需要在子类的构造函数中手动调用父类的构造函数。
class People(object): def __init__(self,name,age): self.name=name self.age=age class Student(People): __amount=100 def __init__(self,name,age,std_id): People.__init__(self,name,age) # 调用父类的构造函数 self.std_id=std_id std1=Student('Sato',20,'202001')
派生
可以在子类中重写父类方法。
class People(object): def __init__(self,name,age): self.name=name self.age=age def identity(self): print("我是人") class Student(People): __amount=100 def __init__(self,name,age,std_id): People.__init__(self,name,age) self.std_id=std_id def identity(self): print("我是学生") std1=Student('Sato',20,'202001') std1.identity() # 我是学生
- Catalog
- About
0%

![[Python]实例方法、类方法、静态方法](https://www.notion.so/image/https%3A%2F%2Fpic3.zhimg.com%2Fv2-a24562cfe485782da76cf8dacae56685_720w.jpg%3Fsource%3D172ae18b?table=block&id=d89f5b34-f69c-4224-91ba-aa446ba4530c&cache=v2)
