Python类的绑定方法和非绑定方法实例解析


Posted in Python onMarch 04, 2020

一、绑定方法

1.对象的绑定方法

首先我们明确一个知识点,凡是类中的方法或函数,默认情况下都是绑定给对象使用的。下面,我们通过实例,来慢慢解析绑定方法的应用。

class People:
  def __init__(self,name,age):
    self.name = name
    self.age = age
  def talk(self):
    pass
  
p = People('xiaohua',18)
print(p.talk)

输出结果:
<bound method People.talk of <__main__.People object at 0x000000F802C69358>>

从上面的输出结果来看,talk()?个类中的方法,是绑定给对象使用的。下面,我在看看另外一种情况。

class People:
  def __init__(self,name,age):
    self.name = name
    self.age = age
  def talk():
    pass

p = People('xiaohua',18)
print(p.talk)

输出结果:
<bound method People.talk of <__main__.People object at 0x000000FF68F39358>>

现在,我们将talk()函数的参数去掉,结果显示与上面是一样。这说明,不管是类中的方法,还是类中函数,默认情况下都是绑定给对象使用的。绑定给对象使用有一种好处,那就是不用手动将对象传入。对象是自动传到类中。如果你不信,我们来看看下面的例子:

class People:
  def __init__(self,name,age):
    self.name = name
    self.age = age
  def talk():
    pass

p = People('xiaohua',18)
print(People.talk)
print(p.talk)

输出结果:
<function People.talk at 0x000000C54E3D0A60> 类来调用仅仅是当作函数使用
<bound method People.talk of <__main__.People object at 0x000000C54E249358>> 而对象来调用则为绑定方法

上面很好说明了,如果类来调用类中的方法,那么这个方法仅仅只是一个函数,那么既然是函数,就不会有自动传值这一功能。来看看下面代码:

class People:
  def __init__(self,name,age):
    self.name = name
    self.age = age
  def talk(self):
    pass
p = People('xiaohua',18)
People.talk() 1
p.talk() 2

#代码1处报错
talk() missing 1 required positional argument: 'self'
#代码2处正常

从上面输出结果来看,当类调用类中的方法时候i,是不会进行自动传值的,也就是说,函数有几个参数,我们就得传递进去几个参数。如果想结果正常运行,那么在类名调用talk()的时候,将参数一一都传递进去。即:

People.talk(312312)

?个参数可以是任意的,但是,必须传递进去。而,当对象调用类中方法时候,则不用传递,如上面的2正常执行。既然知道了区别,那么,我们来看看下面代码:

class People:
  def __init__(self,name,age):
    self.name = name
    self.age = age
  def talk():
    pass

p = People('xiaohua',18)
People.talk() 1
p.talk() 2

# 1处正常执行
# 2 处报错
talk() takes 0 positional arguments but 1 was given

从输出结果来看,People来调用talk()方法时候,并不需要传递参数;而当对象来调用talk()的时候,由于对象调用自己的绑定方法,会自动将对象当作第一个参数传递进去,所以,当类中talk()方法没有带参数时,而你又给它传递了一个,显然是会报错的。

综上所述,我们可以得出以下结论: 

1.凡是类中的方法和函数,都是绑定给对象使用的;

2.绑定方法都有自动传值的功能。传递进去的值,就是对象本身。

3.如果类想调用绑定方法,就必须遵循函数的参数规则,有几个参数,就必须传递几个参数。

聪明的你,可能会问,既然类中的方法都是绑定给对象使用的,那么有没有方法是绑定给类使用的呢?

答案是,当然有!

2.类的绑定方法

 既然类中的方法,默认都是绑定给对象使用,那么,我们要采取一点措施,将类中的绑定方法解除对象绑定关系,进而绑定到类上。

 在python中,引入了@classmethod方法,将类中的方法绑定到类身上。下面看看代码:

class People:
  @classmethod
  def talk(cls):
    pass

p = People()
print(People.talk)

#输出结果
<bound method People.talk of <class '__main__.People'>>

从上述结果可以看出,我们加上了一个装饰器,将类中绑定给对象的方法,绑定到类身上了。我们之前分析过,如果一个方法绑定到谁身上,那么在调用该函数的时候,将自动将该调用者当作第一个参数传递到函数中。但是,绑定到类的方法与绑定到对象方法有一点点不同:

class People:
  def __init__(self,name):
    self.name = name

  @classmethod
  def talk(cls):
    pass
p = People('xiaohua')
print(People.talk)
print(p.talk)

#输出结果
<bound method People.talk of <class '__main__.People'>>
<bound method People.talk of <class '__main__.People'>>

也就是说,当对象在调用类的绑定方法时,也会默认把类当作参数传递进去!所以下面执行正常,并不会因为?个方法绑定到类身上,而对象调用没有传递参数,报错!

class People:
  @classmethod
  def talk(cls):
    pass

p = People()
People.talk()
p.talk()

但是,如果talk()没有参数,则下面代码均会报错。

class People:
  @classmethod
  def talk():
    pass

p = People()
People.talk()
p.talk()
#报错结果
talk() takes 0 positional arguments but 1 was given

两者报错结果一致,这就说明了,当对象来调用类的绑定方法时,也是自动将类传递进去,并不需遵循函数参数传递的规则。

对于类中的绑定方法,也基本上就这两种,不管怎么变化,只要记住以下规则,遇到这种情况,都不会再错。

类中方法默认都是绑定给对象使用,当对象调用绑定方法时,会自动将对象作为第一个参数传递进去;而类来调用,则必须遵循函数参数一一对应的规则,有几个参数,就必须传递几个参数。如果一个方法是用了@classmethod装饰器,那么?个方法绑定到类身上,不管是对象来调用还是类调用,都会将类作为第一个参数传递进去。

二、非绑定方法

上面说了,类中的方法要么是绑定给对象使用,要么是绑定给类使用,那么有没有不绑定给两者使用的函数?

答案:当然有,python给我们提供了@staticmethod,可以解除绑定关系,将一个类中的方法,变为一个普通函数。

下面,我们来看看代码示例:

import hashlib
import time
class MySQL:
  def __init__(self,host,port):
    self.id=self.create_id()
    self.host=host
    self.port=port
  @staticmethod
  def create_id(): #就是一个普通工具
    m=hashlib.md5(str(time.clock()).encode('utf-8'))
    return m.hexdigest()
print(MySQL.create_id) #<function MySQL.create_id at 0x0000000001E6B9D8> #查看结果为普通函数
conn=MySQL('127.0.0.1',3306)
print(conn.create_id) #<function MySQL.create_id at 0x00000000026FB9D8> #查看结果为普通函数

从上面的输出结果,我们可以看出,使用了@staticmethod装饰了一个函数,那么这个函数跟普通函数没有什么区别。既然是普通函数,那么就遵从函数参数传递规则,有几个参数就传递几个参数。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python生成指定长度的随机数密码
Jan 23 Python
数据挖掘之Apriori算法详解和Python实现代码分享
Nov 07 Python
Python读取环境变量的方法和自定义类分享
Nov 22 Python
深入理解Django的自定义过滤器
Oct 17 Python
Python实现的基数排序算法原理与用法实例分析
Nov 23 Python
NumPy 基本切片和索引的具体使用方法
Apr 24 Python
opencv 获取rtsp流媒体视频的实现方法
Aug 23 Python
Python的互斥锁与信号量详解
Sep 12 Python
使用Django实现把两个模型类的数据聚合在一起
Mar 28 Python
如何在django中实现分页功能
Apr 22 Python
用python对excel查重
Dec 07 Python
python实现web邮箱扫描的示例(附源码)
Mar 30 Python
python字符串常用方法及文件简单读写的操作方法
Mar 04 #Python
SpringBoot实现登录注册常见问题解决方案
Mar 04 #Python
Python读取文件内容为字符串的方法(多种方法详解)
Mar 04 #Python
python实现猜拳游戏
Mar 04 #Python
Python单例模式的四种创建方式实例解析
Mar 04 #Python
通过实例解析Python return运行原理
Mar 04 #Python
Python递归函数特点及原理解析
Mar 04 #Python
You might like
re0第二季蕾姆被制作组打入冷宫!艾米莉亚女主扶正,原因唏嘘
2020/04/02 日漫
在PHP中利用XML技术构造远程服务(下)
2006/10/09 PHP
解析smarty 截取字符串函数 truncate的用法介绍
2013/06/20 PHP
php批量删除操作(数据访问)
2017/05/23 PHP
yii2.0框架实现上传excel文件后导入到数据库的方法示例
2020/04/13 PHP
Javascript 表单之间的数据传递代码
2008/12/04 Javascript
用于deeplink的js方法(判断手机是否安装app)
2014/04/02 Javascript
js中利用tagname和id获取元素的方法
2016/01/03 Javascript
jQuery判断元素是否显示 是否隐藏的简单实现代码
2016/05/19 Javascript
仅一个form表单 js实现注册信息依次填写提交功能
2016/06/12 Javascript
JavaScript中递归实现的方法及其区别
2017/09/12 Javascript
微信小程序实现人脸检测功能
2018/05/25 Javascript
详解React native fetch遇到的坑
2018/08/30 Javascript
Vue-CLI项目中路由传参的方式详解
2019/09/01 Javascript
js基础之事件捕获与冒泡原理
2019/10/09 Javascript
Vue-cli assets SubDirectory及PublicPath区别详解
2020/08/18 Javascript
vue 虚拟DOM的原理
2020/10/03 Javascript
vue 使用饿了么UI仿写teambition的筛选功能
2021/03/01 Vue.js
[01:03:51]2018DOTA2亚洲邀请赛 4.7 淘汰赛 VP vs LGD 第三场
2018/04/09 DOTA
Python实现比较两个文件夹中代码变化的方法
2015/07/10 Python
Python中文竖排显示的方法
2015/07/28 Python
python实现爬虫统计学校BBS男女比例(一)
2015/12/31 Python
关于django 数据库迁移(migrate)应该知道的一些事
2018/05/27 Python
Python写一个基于MD5的文件监听程序
2019/03/11 Python
python程序运行进程、使用时间、剩余时间显示功能的实现代码
2019/07/11 Python
使用Python3 poplib模块删除服务器多天前的邮件实现代码
2020/04/24 Python
文言文形式的学生求职信
2013/12/03 职场文书
党校培训思想汇报
2014/01/03 职场文书
保险专业大学生职业规划书
2014/03/03 职场文书
小学生国庆演讲稿
2014/09/05 职场文书
甘南现象心得体会
2014/09/11 职场文书
群众路线教育实践活动批评与自我批评
2014/09/15 职场文书
银行贷款委托书范本
2014/10/11 职场文书
故宫英文导游词
2015/01/31 职场文书
研究生给导师的自荐信
2015/03/06 职场文书
导游词之湖北梁子湖
2019/11/07 职场文书