一、面向对象编程(OOP)
定义
面向过程(Procedure Oriented Programming, POP)是一种程序设计范式,主要关注的是实现功能的步骤,设计时模块化和流程化。面向过程编程是一种以过程为中心的编程方式,它将问题分解成一系列的步骤,然后按顺序执行这些步骤。例如,洗衣机的工作流程可以分解为打开洗衣机、放入衣服、加入洗衣液等步骤。面向过程编程适合处理简单的任务,但不易于扩展和维护
面向对象(Object Oriented Programming, OOP)是一种程序设计范式,主要关注的是对象和类的设计,设计时模块化、封装、继承、多态等特性
- 函数:在面向过程编程中,函数是一段完成特定任务的代码块。函数可以接受输入参数并返回结果,但函数本身不依赖于对象的状态。
- 方法:在面向对象编程(OOP)中,方法是一段定义在类中的代码,用于实现特定的功能。方法可以访问和修改对象的属性,通常通过对象实例来调用。
特性
- 函数:函数是独立的代码块,可以在程序中多次调用,但它们不依赖于对象的状态。函数的调用方式通常是直接通过函数名进行23。
- 方法:方法属于类的一部分,通过对象实例来调用。方法可以访问和修改对象的属性,实现封装、继承和多态等面向对象特性23。
示例
- 面向过程编程示例:假设我们要实现一个功能,计算两个数的和。在面向过程编程中,我们可能会定义一个函数来完成这个任务:
def add(a, b):
return a + b
result = add(5, 3)
print(result) # 输出 8
- 面向对象编程示例:在面向对象编程中,我们可以定义一个类,并在类中定义一个方法来计算两个数的和:
class Calculator:
def add(self, a, b):
return a + b
calc = Calculator()
result = calc.add(5, 3)
print(result) # 输出 8
总结
- 面向过程编程:适合处理简单的任务,但不易于扩展和维护。
- 函数:独立的功能块,适用于各种编程范式。
- 方法:属于类的一部分,适用于面向对象编程,支持封装、继承和多态等特性
面向过程编程与函数式编程对比
二、类和对象
类:类是具有一组相同或者相似特征【属性】和行为【方法】的一系列[多个]对象组合;就是一个模板,模板里可以包含多个函数,函数里实现一些功能
对象:对象是实实在在的一个东西,类的实例化,具象化;则是根据模板创建的实例,通过实例对象可以执行类中的函数
类是对象的抽象化 而对象是类的一个实例
类(Class)由3个部分构成
(1)类的名称: 类名
(2)类的属性: 一组数据
(3)类的方法: 对其进行操作的方法 (行为)
类名:类名应使用首字母大写的驼峰命名法(Pascal命名法)。例如,
ClassName
。私有类名称需要在类名前加一个下划线,例如_ClassName
定义类和对象
定义类和对象
类结构 类名 属性 方法
class 类名:
属性
方法
创建一个对象【类的实例化】
规则格式:对象名=类名()
'''
定义类和对象
类结构 类名 属性 方法
class 类名:
属性
方法
'''
class Person:
'''
属性:人的特征
'''
name = '小明'
'''
实例方法:人的行为
'''
def eat(self):
print('%s爱吃...'%self.name)
pass
def sleep(param):
print('%s爱睡...'%param.name)
pass
pass
'''
创建一个对象【类的实例化】
规则格式:对象名=类名()
'''
xm = Person()
# 调用函数
xm.eat()
xm.sleep()
print('xm对象内存地址',id(xm))
输出:
小明爱吃...
小明爱睡...
xm对象内存地址 1739265662928
三、方法,属性
实例方法:在类的内部,使用def 关键字来定义 类方法必须包含参数 self,且为第一个参数【名字标识可以是其他的名字,但是这个位置必须被占用】;实例方法是归于 类的实例所有
属性:类里面定义的变量。类属性;实例属性。定义在类里面,方法外面的属性称之为类属性,定义在方法里面使用self引用的属性称之为实例属性
在类的内部定义的变量【类属性】;在方法内部定义的【通过类似于self.变量名】 变量,是实例属性
四、self
在Python中,self
是类的实例方法的一个参数,代表类的实例对象本身。实际上,当我们调用一个实例的方法时,Python会自动传递这个实例作为第一个参数,这就是 self
self和对象指向同一个内存地址,可以认为self就是对象的引用
class Student:
def getSelf(self):
print('self对象本身内存地址',id(self))
pass
pass
xm = Student()
print('xm内存地址',id(xm))
xm.getSelf()
输出:
xm内存地址 2489155198928
self对象本身内存地址 2489155198928
1、self作用
(1)访问实例属性和方法
self 提供了一种方式,使得对象的方法可以访问和操作对象的属性
(2)方法链
self 允许对象的方法返回其自身的引用,这使得我们可以链接方法调用
(3)self不是关键字
虽然 self
是一个约定俗成的命名,但它不是Python的关键字。您可以使用任何其他名称,但为了代码清晰和遵循社区习惯,建议使用 self
(4)静态方法和类方法
不是所有的类方法都需要 self 作为它的第一个参数。静态方法和类方法是两种例外。
静态方法:使用 @staticmethod 装饰器定义,它们不接收任何特殊的第一个参数
class MyClass:
@staticmethod
def my_static_method(arg1, arg2):
pass
类方法:使用 @classmethod 装饰器定义,它们接收类作为第一个参数,通常命名为 cls
class MyClass:
@classmethod
def my_class_method(cls, arg1, arg2):
pass
2、self特点
1、self只有在类中定义实例方法的时候才有意义,在调用时候不必传入相应的参数,而是由解释器自动去指向
2、self的名字是可以更改的,可以定义成其他的名字,只是约定俗成的定义成了self
3、self指的是类实例对象本身, 相当于Java中this
五、__init__和__new__
1、__new__方法
- 定义和作用:__new__是一个用于创建对象的特殊方法,它在对象实例化之前被调用。它的主要职责是创建对象并返回一个新的对象实例。__new__方法是一个类方法,必须返回一个新的对象实例
- 使用场景:可以通过重写__new__方法来控制对象的创建过程,例如自定义对象的创建逻辑、返回其他类型的实例等。此外,__new__方法在创建不可变类(如int)时非常重要。
2、__init__方法
- 定义和作用:__init__是一个用于对象初始化的特殊方法,它在对象实例化之后被调用。它的主要职责是对对象的属性进行初始化。__init__方法接收新创建的对象实例作为第一个参数,并在该方法内部对对象的属性进行赋值。
- 使用场景:通常用于设置对象的初始状态,对属性进行赋值等操作。在实际使用中,我们通常只需要重写__init__方法来初始化对象,而对__new__方法的修改需求相对较少。
区别和联系
- 调用顺序:在创建类的实例时,首先调用的是__new__方法,负责创建对象;随后调用的是__init__方法,负责初始化对象的属性。
- 返回值:__new__方法必须返回一个对象实例,而__init__方法不需要返回任何内容
class Person:
def __init__(self,name,age,food):
'''
init初始化方法
init用来做数据属性的初始化(实例的构造方法),接受类的实例self,并对其进行构造
'''
self.name = name
self.age = age
self.food= food
print('----init调用----')
pass
def eat(parma,name,food):
print('%s喜欢吃%s'%(parma.name,parma.food))
pass
def __str__(self):
'''
打印自定义内容格式的对象
:return:
'''
return '%s今年%d岁,喜欢吃%s'%(self.name,self.age,self.food)
pass
def __new__(cls, *args, **kwargs):
'''
创建对象实例的方法
每调用一次,就会生成一个新的对象cls(class的缩写)
场景:可以控制创建对象的一些属性限定,经常用来做单例模式的时候来使用
:param args:
:param kwargs:
'''
print('----new调用----')
# 在这里是真正创建对象实例;必须要返回该实例,否则对象就创建不成功
return object.__new__(cls)
pass
pass
xm = Person('小明',18,'大青菜')
print(id(xm))
xm.eat('小张','鸡蛋')
print(id(xm))
print(xm)
'''
__new__和__init__函数的区别
__new__:类的实例化方法,必须要返回该实例,否则对象就创建不成功
__init__:数据属性的初始化(实例的构造方法),接受类的实例self,并对其进行构造
__new__ 至少有一个参数是cls,代表要实例化的类,此参数在实例化时由python解释器自动提供
__new__ 函数执行要早于__init__函数
'''
输出:
----new调用----
----init调用----
1762567839024
小明喜欢吃大青菜
1762567839024
小明今年18岁,喜欢吃大青菜
六、魔法方法
在python中,有一些内置好的特定的方法,方法名是“__xxx__”,在进行特定的操作时会自动被调用,这些方法称之为魔法方法
常见的魔法方法
__init__方法:初始化一个类,在创建实例对象为其赋值时使用。
__str__方法:在将对象转换成字符串 str(对象) 测试的时候,打印对象的信息。
__new__方法:创建并返回一个实例对象,调用了一次,就会得到一个对象。
__class__方法:获得已知对象的类 ( 对象.__class__)。
__del__方法:对象在程序运行结束后进行对象销毁的时候调用这个方法,来释放资源。
七、析构方法__del__
当一个对象被删除或者被销毁时,python解释器也会默认调用一个方法,这个方法为__del__()方法,也称为析构方法
程序执行结束自动调用__del__方法;对象被删除时也会自动调用__del__方法
也可手动调用 del 对象名 删除对象
1、当整个程序脚本执行完毕后会自动调用__del__方法
2、当对像被手动销毁时也会自动调用 __del__ 方法
3、析构函数一般用于资源回收,利用__del__方法销毁对象回收内存等资源
class Animal:
def __init__(self,name):
self.name=name
print('init构造初始化方法')
pass
def __del__(self):
# 主要的应用就是来操作 对象的释放,一旦释放完毕,对象便不能在使用
# 当在某个作用域下面,没有被使用【引用】的情况下,解析器会自动的调用此函数,来释放内存空间
print('析构方法')
print('%s 这个对象 被彻底清理了 内存空间也释放了'%self.name)
pass
cat=Animal('小猫')
# del cat #手动的去清理删除对象,会指定__del__函数;再去调用对象方法报错:NameError: name 'cat' is not defined
print(cat.name)
input('程序等待中.....')
print('*'*20)
dog=Animal('小狗')
输出:
init构造初始化方法
小猫
程序等待中.....11
********************
init构造初始化方法
析构方法
小猫 这个对象 被彻底清理了 内存空间也释放了
析构方法
小狗 这个对象 被彻底清理了 内存空间也释放了
八、函数和方法区别
在Python中,函数和方法是两个不同的概念。
1、函数
函数是一段独立的可重用代码块,可以在程序的任何地方调用执行。函数通常用于封装可重用的代码逻辑,以便在需要时进行调用。函数可以接受输入参数,并可以返回一个值作为结果。例如:
def add(a, b):
return a + b
result = add(5, 3)
print(result) # 输出:8
2、方法
方法是与对象(或类)相关联的函数。方法是定义在类中的函数,用于执行特定对象的操作。方法与对象之间存在着紧密的关联,因此它们可以访问和操作对象的属性和状态。方法在类的定义中被声明,并通过对象来调用。例如:
class MyClass:
def __init__(self, value):
self.value = value
def double(self):
return self.value * 2
obj = MyClass(10)
print(obj.double()) # 输出:20
区别和联系
- 定义位置:函数定义在模块级别,而方法定义在类中。
- 调用方式:函数通过模块名或直接调用,方法通过对象实例调用。
- 作用范围:函数不依赖于任何对象,而方法依赖于特定的对象实例,可以访问和修改对象的属性。
- 用途:函数用于封装独立的代码逻辑,方法用于操作对象的特定行为和状态
根本区别:
-
与类和实例无绑定关系的function都属于函数(function)
-
与类和实例有绑定关系方法(method)
表层区别:
-
方法是自动传参self,函数是主动传参
-
函数是直接写文件中而不是class中,方法是只能写在class中。
-
函数定义的方式 def关键字 然后接函数名 再是括号 括号里面写形参也可以省略不写形参
-
方法定义的方式 首先方法是定义在类中的其他他大体和函数定义差不多,这里需要注意的一点就是方法必须带一个默认参数(相当于this),静态方法除外
调用区别:
-
函数的调用:函数的调用是直接写 函数名(函数参数1,函数参数2,......)
-
方法的调用:方法是通过对象点方法调用的(这里是指对象方法)