0
点赞
收藏
分享

微信扫一扫

Python - 面向对象编程

苦茶如歌 2022-02-11 阅读 45

python完全采用了面向对象的思想,是真正面向对象的编程语言,支持面向对象的基本操作,例如:继承、多态、封装。
python中一切皆对象。python支持面向对象、面向过程、函数式编程等多种编程范式。

目录

面向对象和面向过程的区别

  • 面向过程编程更加关注的是“程序的逻辑流程”,是一种“执行者”思维,适合编写小规模的程序
  • 面向对象编程更加关注的是“软件中对象之间的关系”,是一种“设计者”思维,适合编写大规模的程序
  • 面向对象思考方式:遇到复杂问题,先从问题中找名词(面向过程更多的是找动词),然后确立这些名词哪 些可以作为类,再根据问题需求确定的类的属性和方法,确定类之间的关系。

· 面向对象和面向过程的总结:
都是解决问题的思维方式,都是代码组织的方式。
解决简单问题可以使用面向过程。
解决复杂问题:宏观上使用面向对象把握,微观处理上仍然是面向过程。

类的定义

在这里插入图片描述
我们通过类定义数据类型的属性(数据)和方法(行为),也就是说,“类将行为和状态打 包在一起”。
对象是类的具体实体,一般称为“类的实例”。
在这里插入图片描述
从一个类创建对象时,每个对象会共享这个类的行为(类中定义的方法),但会有自己的属 性值(不共享状态)。更具体一点:“方法代码是共享的,属性数据不共享”。
Python 中,“一切皆对象”。类也称为“类对象”,类的实例也称为“实例对象”。

定义类的语法格式如下:

要点如下:
1.类名必须符合“标识符”的规则;一般规定,首字母大写,多个单词使用“驼峰原则”。
2. 类体中我们可以定义属性和方法。
3. 属性用来描述数据,方法(即函数)用来描述这些数据相关的操作。

class student():
    def __init__(self, name, score):
        self.name = name
        self.score = score
    
    def print_score(self):
        print('name:{0} score:{1}'.format(self.name, self.score))

s1 = student('sherry',100)
s2 = student('lily',90)
s1.print_score()
s2.print_score()

输出:
name:sherry score:100
name:lily score:90

__init__构造方法和__new__方法

更进一步的说,一个 Python 对象包含如下部分:

创建对象,我们需要定义构造函数**init()**方法。构造方法用于执行“实例对象的初始化工 作”,即对象创建后,初始化当前对象的相关属性,无返回值

init()的要点如下:
1.名称固定,必须为:init(),第一个参数固定,必须为:self。 self 指的就是刚刚创建好的实例对象
2.构造函数通常用来初始化实例对象的实例属性
3.通过“类名(参数列表)”来调用构造函数。调用后,将创建好的对象返回给相应的变量
4.init()方法:初始化创建好的对象,初始化指的是:“给实例属性赋值”
5.new()方法: 用于创建对象,但我们一般无需重定义该方法。
6.如果我们不定义__init__方法,系统会提供一个默认的__init__方法。如果我们定义了带参 的__init__方法,系统不创建默认的__init__方法

注:1. Python 中的 self 相当于 C++中的 self 指针,JAVA 和 C#中的 this 关键字。Python 中, self 必须为构造函数的第一个参数,名字可以任意修改。但一般遵守惯例,都叫做 self。

实例属性和实例方法

实例属性

实例属性是从属于实例对象的属性:
1.实例属性一般在__init()__中定义
2.在本类的其它实例方法中,也是通过self.属性名进行访问
3.创建实例对象后,通过实例对象访问:obj.属性名

实例方法

实例方法是从属于实例对象的方法,
实例方法的定义格式如下:

调用方法的格式如下:

要点:
1.定义实例方法时,第一个参数必须为 self。和前面一样,self 指当前的实例对象。 2. 调用实例方法时,不需要也不能给 self 传参。self 由解释器自动传参。

函数和方法的区别

  1. 都是用来完成一个功能的语句块,本质一样。
  2. 方法调用时,通过对象来调用。方法从属于特定实例对象,普通函数没有这个特点。
  3. 直观上看,方法定义时需要传递 self,函数不需要。

实例对象的方法调用本质

在这里插入图片描述

class student():
    def __init__(self, name, score):
        self.name = name
        self.score = score
    
    def print_score(self):
        print('name:{0} score:{1}'.format(self.name, self.score))

s1 = student('sherry',100)
s1.print_score()
student.print_score(s1)

输出:
name:sherry score:100
name:sherry score:100

其他操作

  1. dir(obj)可以获得对象的所有属性、方法
  2. obj.dict 对象的属性字典
class student():
    def __init__(self, name, score):
        self.name = name
        self.score = score
    
    def print_score(self):
        print('name:{0} score:{1}'.format(self.name, self.score))

s1 = student('sherry',100)
print(dir(s1))		#s1对象的所有属性、方法
print(s1.__dict__). #student对象的属性字典

输出:
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'name', 'print_score', 'score']
{'name': 'sherry', 'score': 100}
  1. pass 空语句
  2. isinstance(对象,类型) 判断“对象”是不是“指定类型”

类对象

类定义格式中,“class 类名:”。实际上,当解释器执行 class 语句时, 就会创建一个类对象,也称为类型对象type)。

class student():
    def __init__(self, name, score):
        self.name = name
        self.score = score
    
    def print_score(self):
        print('name:{0} score:{1}'.format(self.name, self.score))

print(type(student))
print(id(student))

输出:
<class 'type'>
140442115598784

类属性和类方法

类属性

类属性是从属于”类对象“的属性,也称为类变量。由于类属性从属于类对象,可以被所有实例对象共享。
类属性的定义如下:

class 类名:
	类变量名 = 初始值

在类中或者类外,我们可以通过:“类名.类变量名”来读写。

class student():
    school = 'ucas'
    count = 0. # 类变量 用于统计初始化了多少个学生
    def __init__(self, name, score):
        self.name = name
        self.score = score
        student.count += 1 # 学生数量+1
    
    def print_score(self):
        print('school.{2} name:{0} score:{1}'.format(self.name, self.score,student.school))

s1 = student('sherry',100)
s1.print_score()
print(student.school)
print(student.count)

输出:
school.ucas name:sherry score:100
ucas
1

类方法

类方法是从属于类对象的方法,类方法通过装饰器@classmethod来定义,格式如下:

要点:
1.@classmethod 必须位于方法上面一行
2. 第一个 cls 必须有;cls 指的就是“类对象”本身;
3. 调用类方法格式:“类名.类方法名(参数列表)”。 参数列表中,不需要也不能给 cls 传 值。
4. 类方法中访问实例属性和实例方法会导致错误
5. 子类继承父类方法时,传入 cls 是子类对象,而非父类对象

# 测试类方法
class student():
    school = 'ucas'
    count = 0

    @classmethod
    def print_school(cls):
        print('school:{0}'.format(cls.school))

    def __init__(self, name, score):
        self.name = name
        self.score = score
        student.count += 1
    
    def print_score(self):
        print('school.{2} name:{0} score:{1}'.format(self.name, self.score,student.school))

student.print_school()

输出:
school:ucas

静态方法

python中允许定义与“类对象”无关的方法,称为“静态方法”。
”静态方法“和在模块中定义普通函数没有区别,只不过“静态方法”放到了“类的名字空间里面”,需要通过“类去调用”。
静态方法通过装饰器@staticmethod来定义,格式如下:

要点:
1.@staticmethod 必须位于方法上面一行
2. 调用静态方法格式:“类名.静态方法名(参数列表)”。
3. 静态方法中访问实例属性和实例方法会导致错误

# 测试静态方法
class student():
    school = 'ucas'
    count = 0

    @classmethod
    def print_school(cls):
        print('school:{0}'.format(cls.school))
    
    @staticmethod
    def add(a,b):
        print(a+b)

    def __init__(self, name, score):
        self.name = name
        self.score = score
        student.count += 1
    
    def print_score(self):
        print('school.{2} name:{0} score:{1}'.format(self.name, self.score,student.school))

student.add(100,200)

输出:
300

del()方法(析构函数)和垃圾回收机制

  • __del__方法称为“析构方法”,用于实现对象被销毁时所需的操作,比如:释放对象占用的资源,例如:打开的文件资源、网络连接等。
  • python中实现自动的垃圾回收,当对象没有被引用时(引用计数为0),由垃圾回收器调用__del__方法。
  • 我们也可以用del语句删除对象,从而保证调用__del__方法。
    系统会自动提供__del__方法,一般不需要自定义析构方法。
# 测试析构方法
class person():
    def __del__(self):
        print('销毁对象')

p1 = person()
p2 = person()
del p1
print('over')

输出:
销毁对象
over
销毁对象

call()方法和可调用对象

定义了__call__方法的对象,称为“可调用对象”,即该对象可以像函数一样被调用。

# 测试可调用方法
class caculate():
    def __call__(self,a,b):
        print(a+b)

cacul = caculate()
cacul(10,20)

输出:
30
举报

相关推荐

0 条评论