【python基础之面向对象的绑定方法与非绑定方法】--面向对象的绑定方法与非绑定方法
1.【python入门之相关语言了解】---开发语言与其他2.【python入门之pycharm篇】--如何安装pycharm以及如何安装python解释器3.【python工具指南】pycharm相关快捷键---windows+mac合集4.【python入门之pip换源问题】---pip换源的方式5.【python小记】---PE8规范简述6.【python入门之虚拟环境与系统环境】---虚拟环境的创建方式及使用7.【python入门之常量与变量】---常量与变量小记8.【python入门之基本数据类型的学习】---基本数据之数字类型9.【python入门之基本数据类型的学习】---基本数据类型(列表、字符串)【二】10.【python入门之基本数据类型】---基本数据类型(字典、布尔)【三】11.【python入门之基本数据类型】---基本数据类型(元组、集合)【四】12.【python入门之程序与用户交互】---程序与用户交互13.【python入门之基本运算符】---基本运算符14.【python入门之流程控制语句】---流程控制语句15.【python入门之垃圾回收机制】---python 垃圾回收机制16.【python入门之文件操作】---文件操作17.【python入门之文字符编码】---字符编码18.【python基础之可变和不可变数据类型】---python之栈的介绍19.【python基础之可变和不可变数据类型】--- python之堆的介绍20.【python基础之可变和不可变数据类型】--- python堆栈的相关应用21.【python基础之数据类型的内置方法】--- 数据类型的内置方法22.【python入门之深浅拷贝】---python 深浅拷贝23.【python入门之异常处理】---python 异常处理24.【python基础之函数】--- 函数入门25.【python基础之命名空间与作用域】---命名空间与作用域26.【python基础之函数对象和闭包】 --- 函数对象与闭包27.【python基础之装饰器】---装饰器28.【python基础之迭代器】 --- 迭代器29.【python基础之三元表达式】--- 三元表达式30.【python基础之列表生成式】---列表生成式31.【python基础之生成器】---生成器32.【python基础之模块介绍】---模块33.【python基础之包介绍】---包34.【python扩展之软件开发目录规范】---软件开发目录规范35.【python常用模块之OS模块简介】---OS模块36.【python常用模块之random模块简介】---random模块37.【python常用模块之time时间模块】---时间模块(time/datetime)38.【python常用模块之subprocess模块】---subprocess模块39.【python常用模块之sys模块】---系统模块(sys)40.【Python常用模块之logging模块】---日志输出功能(示例代码)41.【python--- ATM+SHOPPING】42.【python基础之面向对象介绍】--- 面向对象
43.【python基础之面向对象的绑定方法与非绑定方法】--面向对象的绑定方法与非绑定方法
44.【python网络编程相关】 ----操作系统相关了解45.【python之DRF学习】DRF入门了解46.【python之DRF学习】三大方法之认证47.【python之接口工具】利用docker-compose搭建Yapi48.【python之DRF学习】drf全局异常49.【python之DRF学习】 drf之接口文档介绍及使用50.【python之DRF学习】drf之jwt使用【一】类属性和对象属性
1、定义
类属性:类里面方法外面定义的变量称为类属性。类属性所属于类对象并且多个实例对象之间共享同一个类属性,说白了就是类属性所有的通过该类实例化的对象都能共享。
实例属性:实例属性和具体的某个实例对象有关系,并且一个实例对象和另外一个实例对象是不共享属性的,说白了实例属性只能在自己的对象里面使用,其他的对象不能直接使用,因为self是谁调用,它的值就属于该对象。
2、总结
访问类属性和对象属性总结:
类的属性可以使用类名访问(推荐) 类的属性也可以通过对象访问(不推荐)
对象的属性可以使用对象访问(推荐) 对象的属性不可以通过类名访问(报错)
在项目中 类的属性一般通过类名访问 对象的属性一般通过对象访问
修改类的属性和对象的属性的总结:
类可以修改类的属性 对象在修改类的属性的时候,其实是动态的给当前对象添加了一个属性.其他的对象不能访问修改后的值.
对象可以修改对象的属性 类也可以修改对象的属性.
在项目中 一般情况下,通过类名去修改类的属性 通过对象名去修改对象的属性.
3、示例
# 【一】类属性 : 分为两种 一种是数据属性 一种是函数属性
class Student:
# 这个 school 其实就是数据属性,对象可以任意调用
school = '清华大学'
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
# 函数属性
def read(self):
print(f'正在读书')
# 实例化类得到类对象
stu = Student(name='dream', age=18, gender='male')
# 【一】访问数据属性的两种方法
# print(Student.__dict__) # {'__module__': '__main__', 'school': '清华大学', '__init__': <function Student.__init__ at 0x0000029FF85A4400>, 'read': <function Student.read at 0x0000029FF860F920>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None}
# 一种是 通过 __dict__ 的字典取键
# print(Student.__dict__['school']) # 清华大学
# 另一种直接通过 类名.属性 获取到属性的值
# print(Student.school) # 清华大学
# 对象可以通过 __dict__ 获取到类属性码?
# print(stu.__dict__) # {'name': 'dream', 'age': 18, 'gender': 'male'}
# print(stu.__dict__['school']) # {'name': 'dream', 'age': 18, 'gender': 'male'}
# print(stu.school) # 清华大学
# 【二】访问函数属性的两种方法
# print(Student.__dict__)
# 类调用对象函数属性 因为有一个位置参数叫 self ,类调用需要传入 self 实例化出来的对象
Student.__dict__['read'](stu)
# 对象调用函数属性,这里的位置参数会自动将调用该方法的对象传入,所以不用传self参数
# print(stu.__dict__) # 这里是没有的
stu.read()
【二】对象属性的查找顺序
# 对象的属性查找顺序
# 【1】首先从自己本身开始找 从 stu.__dict__ 开始找
# 【2】找不到再去实例化他的类中找 从 Student.__dict__ 开始找
# 【3】别的方法没有初始化过这个属性,并且这个类没有继承其他的类
# 【4】找不到就报错了
# 总结 : obj(对象) ---> class(类) ---> gender_class(父类) ---> 找不到直接报错
【三】类的特殊方法
class Cat():
...
from new_class import Cat
# 【一】定义一个类
class Animal():
...
class BlackCat(Cat):
...
class People:
'''这是一个人类的注释'''
def __init__(self, name, age):
self.name = name
self.age = age
def run(self):
'''
这是一个注释
:return:
'''
print(f"{self.name} can run!")
# def login_auth(func):
# def inner():
# # 查看函数的名字
# print(func.__name__) # index
# return func()
# return inner
# @login_auth
# def index():
# ...
# index()
# 【1】实例化类得到对象
person = People(name='dream', age=18)
# 【二】类的名字
# def check_class_name(class_name):
# print(class_name.__name__)
# check_class_name(class_name=People)
# check_class_name(class_name=Animal)
# 【三】查看类的文档字符串,查看类中的多行注释内容 ('''''' / """""")
# def check_class_name(class_name):
# print(class_name.__doc__)
# check_class_name(class_name=People) # 这是一个人类的注释
# check_class_name(class_name=Animal) # None
# 【四】类的字典属性
# def check_class_name(class_name):
# print(class_name.__dict__)
# check_class_name(class_name=People) # 这是一个人类的注释
# check_class_name(class_name=Animal) # None
# 【五】查看类定义所在的模块
# def check_class_name(class_name):
# print(class_name.__module__)
# check_class_name(class_name=People) # __main__
# check_class_name(class_name=Animal) # __main__
# check_class_name(class_name=Cat) # new_class
# 【六】查看当前实例所对应的类
def check_class_name(obj_name):
print(obj_name.__class__)
check_class_name(obj_name=People(name='dream',age=18)) # __main__
check_class_name(obj_name=Animal()) # __main__
check_class_name(obj_name=Cat()) # new_class
【四】绑定方法与非绑定方法
1、绑定方法
1.1、定义
凡是类中的方法或函数,默认情况下都是绑定给对象使用的。
类中不被任何装饰器装 装饰的方法或函数,默认情况下都是绑定给对象使用的,例如 def fun() 或 def fun(self)
用@classmethod装饰的方法是绑定到类上的
用@staticmethod修饰的方法,是解除所有绑定关系作为普通函数存在,为非绑定方法
1.2、特点
其特点是「调用方」本身自动作为第一个参数传入。
一个方法绑定到谁身上,谁来调用,该调用者当作第一个参数会自动传参。
绑定给对象:调用方是一个「对象」,该对象自动传入(调用方是『类』,需要手动传入第一个参数)
绑定给类:调用方是「类|对象」,该类自动传入
1.3、分类
绑定到类的方法:
用classmethod装饰器装饰的方法就是类绑定方法(「对象」也可调用「类绑定方法」,但仍将类当作第一个参数传入)。
类.boud_method(),自动将「类」当作第一个参数传入
对象.boud_method(),自动将「类」当作第一个参数传入
绑定到对象的方法:
没有被任何装饰器装饰的方法,默认是绑定给对象使用的方法。
对象.boud_method(args2,args3),自动将“对象”当作第一个参数传入。
类.boud_method(args1,args2,args3),需按照参数规则一一传递所有参数
-- “类”可以调用“对象的绑定方法”,但不会自动传值,需按照参数规则一一传递所有参数
2、非绑定方法
2.1、定义
在类内部用@staticmethod装饰的函数即「非绑定方法」,就是普通函数。
2.2、特点
不与类或对象绑定
没有自动传参的效果
『类和对象』都可以调用
不管谁来调用,都不会自动传值
2.3、疑问点
自由方法应该也算非绑定方法?
-- 自由方法是对象的绑定方法,绑定给对象。
如果定义staticmethod时传self或cls,还算是非绑定方法吗?
-- 在静态方法里面 访问不了 类或者实例 的任何属性。 一般不需要传参数self
【注意】在类中直接定义的函数,没有被任何装饰器装饰的,都是绑定到对象的方法,不是普通函数,对象调用该方法会自动传值
3、总结
当「对象」调用「对象的绑定方法」时,默认把对象自己当做第一个参数传递到函数中
当 「类」 调用「对象的绑定方法」时,不会进行自动传值的;也就是说,函数有几个参数,我们就得传递进去几个参数。
当「类|对象」在调用「类的绑定方法」时,会默认把 类 当作参数传递进去。
当「类|对象」在调用「非绑定方法」时,不会自动传值
4、代码及部分文字描述
# 【一】绑定方法:绑定给某个目标(类或对象)的方法 --- 动态方法
# 【1】绑定给对象的方法
# class Student: # 类的属性有两种:一种是数据属性 一种是函数属性
# # 【1】数据属性
# school = '清华大学'
#
# # 【2】函数属性
# def read(self, name):
# print(f' {name} 正在读书')
# (1)实例化得到对象,对象调用对象的绑定方法
# stu = Student()
# 在这里对象调用绑定给对象的绑定方法时,会自动将当前对象作为第一个参数传入
# stu.read('dream') # dream 正在读书
# (2)类调用对象的绑定方法
# Student.read('dream') # Student.read() missing 1 required positional argument: 'name'
# Student.read(name='dream') # TypeError: Student.read() missing 1 required positional argument: 'self'
# 如果是类调用对象的绑定方法,那么就需要将对象作为参数传进去
# stu = Student()
# Student.read(stu,'dream') # dream 正在读书
# 在Python里面一切皆对象,八大基本数据类型全是对象,包括 None
# Student.read('521','dream')
# Student.read(None,'dream')
# (3)总结:
# 对象调用绑定给对象的方法,不需要传额外的参数,直接能调用执行
# 类调用绑定给对象的方法,第一个位置参数必须是实例化得到的对象,加其他可能传入的额外的参数
# 【2】绑定给类的方法
# class Student: # 类的属性有两种:一种是数据属性 一种是函数属性
# # 【1】数据属性
# school = '清华大学'
#
# # 【2】函数属性 -- 绑定给对象的方法
# def read(self, name):
# print(f' {name} 正在读书')
# # 【3】函数属性 --- 绑定给类的方法
# @classmethod # 装饰器的语法糖
# def write(cls,name):
# print(cls) # <class '__main__.Student'>
# print(f' {name} 正在写作业')
# (1)对象调用绑定给类的方法,这里会自动检索到当前实例化得到当前对象的类,然后将类作为cls的参数传入
# stu = Student()
# stu.write(name='dream')
# (2)类调用绑定给类的方法,将调用此方法的类,作为cls的参数自动传入
# Student.write(name='hope')
# (3)总结
# 对象调用绑定给类的方法,不需要传入额外的参数,会自动将当前实例化此对象的类作为参数传入
# 类调用绑定给类的方法,不需要额外的传入参数,会自动将调用次方法的类作为参数传进去
# 【二】非绑定方法:不绑定给某个目标(类或对象)的方法 -- 静态方法
class Student: # 类的属性有两种:一种是数据属性 一种是函数属性
# 【1】数据属性
school = '清华大学'
# 【2】函数属性 -- 绑定给对象的方法
def read(self,name):
print(name)
print(f' {name} 正在读书')
# 【3】函数属性 --- 绑定给类的方法
@classmethod # 装饰器的语法糖
def write(cls, name):
print(cls) # <class '__main__.Student'>
print(f' {name} 正在写作业')
# 【3】函数属性 --- 非绑定方法,本质上其实就是一个普普通通的函数
@staticmethod
def run(name):
print(f' {name} 正在跑步')
# (1)对象调用非绑定方法.不需要传额外的参数
# stu = Student()
# stu.run(name='dream')
# stu.read(name='dream')
# (2)类调用绑定方法.不需要传额外的参数
# Student.run(name='hope')
# Student.read(name='hope')
# (3)总结:
# 对象调用非绑定方法,不需要传额外的参数
# 类调用非绑定方法,不需要传额外的参数
【五】绑定方法与非绑定方法总结
# 总结 : 绑定方法 与 非绑定方法
# 【一】概念上来说
# 绑定方法 : 就是绑定给某个目标(类或对象)的方法才叫绑定方法
# 非绑定方法:不绑定给某个目标(类或对象)的方法叫非绑定方法
# 【二】调用方式上来看
# 绑定给对象的方法:对象可以任意调用,类可能会受到某些限制
# 绑定给类的方法:类可以任意调用,对象可能会受到某些影响
# 非绑定方法:不受类和对象的限制,可以任意调用
# 【三】定义方式上来看
class Person():
# 【1】绑定给对象的方法:正常我们定义的所有方法都是绑定给对象的方法
# 在定义方法的时候,会自动补全 self
def read(self):
print(self)
# 【2】绑定给类的方法:用装饰器装饰我们想要绑定给类的方法
# 在定义方法的时候,会自动补全 cls
@classmethod
def write(cls):
print(cls)
# 【3】非绑定方法:既不绑定给对象也不绑定给类
# 在定义方法的时候,不会自动补全参数
@staticmethod
def run():
...
# 【四】三种函数的调用
# 【1】绑定给对象的方法
# (1)对象调用
p = Person()
p.read()
# (2)类调用,self的值就是实例化得到的对象
Person.read(Person())
# 【2】绑定给类的方法
# (1)类调用
Person.write()
# (2)对象调用
p = Person()
p.write()
# 【3】静态方法(非绑定方法)
# (1)对象调用
p = Person()
p.run()
# (2)类调用
Person.run()
本文来自博客园,作者:Unfool,转载请注明原文链接:https://www.cnblogs.com/queryH/p/17945402
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!