Python中类和对象的绑定及非绑定方法详解

作者:追忆MHyourh 时间:2023-03-13 12:27:32 

类中定义的方法大致可以分为两类:绑定方法和非绑定方法。其中绑定方法又可以分为绑定到对象的方法和绑定到类的方法。

一、绑定方法

1 对象的绑定方法

在类中没有被任何装饰器修饰的方法就是 绑定到对象的方法,这类方法专门为对象定制。

class Person:
   country = "China"

def __init__(self, name, age):
       self.name = name
       self.age = age

def speak(self):
       print(self.name + ', ' + str(self.age))

p = Person('Kitty', 18)
print(p.__dict__)
{'name': 'Kitty', 'age': 18}

print(Person.__dict__['speak'])
<function Person.speak at 0x10f0dd268>

speak即为绑定到对象的方法,这个方法不在对象的名称空间中,而是在类的名称空间中。

通过对象调用绑定到对象的方法,会有一个自动传值的过程,即自动将当前对象传递给方法的第一个参数(self,一般都叫self,也可以写成别的名称);若是使用类调用,则第一个参数需要手动传值。

p = Person('Kitty', 18)
p.speak()  # 通过对象调用
#输出
Kitty, 18

Person.speak(p)  # 通过类调用
#输出
Kitty, 18

2 类的绑定方法

类中使用 @classmethod 修饰的方法就是绑定到类的方法。这类方法专门为类定制。通过类名调用绑定到类的方法时,会将类本身当做参数传给类方法的第一个参数。

class Operate_database():
   host = '192.168.0.5'
   port = '3306'
   user = 'abc'
   password = '123456'

@classmethod
   def connect(cls):  # 约定俗成第一个参数名为cls,也可以定义为其他参数名
       print(cls)
       print(cls.host + ':' + cls.port + ' ' + cls.user + '/' + cls.password)

Operate_database.connect()

输出

<class '__main__.Operate_database'>
192.168.0.5:3306 abc/123456

通过对象也可以调用,只是默认传递的第一个参数还是这个对象对应的类。

Operate_database().connect()  # 输出结果一致

#输出
<class '__main__.Operate_database'>
192.168.0.5:3306 abc/123456

二、非绑定方法

在类内部使用 @staticmethod 修饰的方法即为非绑定方法,这类方法和普通定义的函数没有区别,不与类或对象绑定,谁都可以调用,且没有自动传值的效果。

import hashlib

class Operate_database():
   def __init__(self, host, port, user, password):
       self.host = host
       self.port = port
       self.user = user
       self.password = password

@staticmethod
   def get_passwrod(salt, password):
       m = hashlib.md5(salt.encode('utf-8'))  # 加盐处理
       m.update(password.encode('utf-8'))
       return m.hexdigest()

hash_password = Operate_database.get_passwrod('lala', '123456')  # 通过类来调用
print(hash_password)

#输出
f7a1cc409ed6f51058c2b4a94a7e1956
p = Operate_database('192.168.0.5', '3306', 'abc', '123456')
hash_password = p.get_passwrod(p.user, p.password)  # 也可以通过对象调用
print(hash_password)
#输出
0659c7992e268962384eb17fafe88364

简而言之,非绑定方法就是将普通方法放到了类的内部。

三、练习

假设我们现在有一个需求,需要让Mysql实例化出的对象可以从文件settings.py中读取数据。

# settings.py
IP = '1.1.1.10'
PORT = 3306
NET = 27
# test.py
import uuid

class Mysql:
   def __init__(self, ip, port, net):
       self.uid = self.create_uid()
       self.ip = ip
       self.port = port
       self.net = net

def tell_info(self):
       """查看ip地址和端口号"""
       print('%s:%s' % (self.ip, self.port))

@classmethod
   def from_conf(cls):
       return cls(IP, NET, PORT)

@staticmethod
   def func(x, y):
       print('不与任何人绑定')

@staticmethod
   def create_uid():
       """随机生成一个字符串"""
       return uuid.uuid1()

#学习中遇到问题没人解答?小编创建了一个Python学习交流:711312441
# 默认的实例化方式:类名()
obj = Mysql('10.10.0.9', 3307, 27)
obj.tell_info()

10.10.0.9:3307

1 绑定方法小结

如果函数体代码需要用外部传入的类,则应该将该函数定义成绑定给类的方法

如果函数体代码需要用外部传入的对象,则应该将该函数定义成绑定给对象的方法

# 一种新的实例化方式:从配置文件中读取配置完成实例化
obj1 = Mysql.from_conf()
obj1.tell_info()

#输出
1.1.1.10:27

print(obj.tell_info)
#输出
<bound method Mysql.tell_info of <__main__.Mysql object at 0x10f469240>>

print(obj.from_conf)
#输出
<bound method Mysql.from_conf of <class '__main__.Mysql'>>

2 非绑定方法小结

如果函数体代码既不需要外部传入的类也不需要外部传入的对象,则应该将该函数定义成非绑定方法/普通函数

obj.func(1, 2)
#输出
不与任何人绑定

Mysql.func(3, 4)
#输出
不与任何人绑定

print(obj.func)
#输出
<function Mysql.func at 0x10f10e620>

print(Mysql.func)
#输出
<function Mysql.func at 0x10f10e620>

print(obj.uid)
#输出
a78489ec-92a3-11e9-b4d7-acde48001122

来源:https://segmentfault.com/a/1190000043493678

标签:Python,类,对象,绑定
0
投稿

猜你喜欢

  • ASP.NET(C#)读取Excel的文件内容

    2023-07-10 22:38:35
  • php的PDO事务处理机制实例分析

    2024-05-11 09:45:30
  • python爬虫判断招聘信息是否存在的实例代码

    2022-09-14 20:38:04
  • 详解Python Opencv和PIL读取图像文件的差别

    2023-09-14 07:36:00
  • SQL指令植入式攻击的危害及其防范措施

    2008-12-19 14:07:00
  • python 正则表达式 概述及常用字符

    2023-03-03 07:16:15
  • 网页设计之关于素材和言志

    2008-03-23 13:46:00
  • Golang中HttpRouter路由的使用详解

    2024-04-30 10:04:23
  • 在Python中将函数作为另一个函数的参数传入并调用的方法

    2023-04-10 07:32:26
  • Python通过m3u8文件下载合并ts视频的操作

    2023-07-19 04:36:51
  • Django web框架使用url path name详解

    2022-01-06 19:43:59
  • Golang的strings.Split()踩坑记录

    2024-02-22 11:34:05
  • MySQL 字符串截取相关函数小结

    2024-01-14 21:37:14
  • python日志通过不同的等级打印不同的颜色(示例代码)

    2022-08-18 01:47:25
  • ASP使用连接MYSQL数据库全攻略

    2007-09-23 09:06:00
  • MySQL中查询的有关英文字母大小写问题的分析

    2024-01-27 05:59:47
  • 关于安卓手机微信浏览器中使用XMLHttpRequest 2上传图片显示字节数为0的解决办法

    2024-04-29 13:14:31
  • 通过自学python能找到工作吗

    2021-07-24 04:26:33
  • vue项目无法删除的问题及解决

    2024-05-02 17:08:36
  • Python AES加密模块用法分析

    2021-05-29 05:13:58
  • asp之家 网络编程 m.aspxhome.com