🍖类和对象的绑定方法与非绑定方法

引入

类的定义方法大致可以分为两类 : 绑定方法和非绑定方法

其中绑定方法又可以分为绑定到对象的方法和绑定到类的方法

一.绑定方法

1.对象的绑定方法

  • 在类中没有被任何装饰器修饰的方法就是绑定给对象的方法, 这类方法专门为对象定制的
class Person:
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def print_name(self):
        print(self.name)

    def print_age(self):
        print(self.age)

P1 = Person('shawn',22)
P1.print_name()  # shawn
print(Person.__dict__['print_name'])  # <function Person.print_name at 0x00000168C1A54DC8>

通过__dict__查看类的属性字典, 我们可以发现 print_name 即为绑定到对象的方法, 这个方法不在对象的名称空间中, 而是在类的名称空间中

对象调用绑定给对象的方法, 这里会有一个自动传值的过程, 即自动将当前对象传递给方法的第一个参数, 也就是 "self" (约定俗成的叫self, 也可以叫别的)

若是类调用, 则第一个参数需要手动传值

🍖先实例出一个对象
P1 = Person('shawn',22)

🍖对象调用绑定给对象的方法
P1.print_name()       # shawn 

🍖类调用绑定给对象的方法
Person.print_name(P1) # shawn

2.类的绑定方法

  • 在类中使用 @classmethod 修饰的方法就是绑定给类使用的方法, 这类方法专门为类定制的
  • 通过类名调用绑定给类的方法的时候, 会将类本身当做参数传给类方法的第一个参数 "cls"(和self 类似,也可以叫别的名字)
class Computer:
    name = "痞老板"
    age = 19119
    money = 90999

    @classmethod
    def user_info(cls):
        print(cls)
        print(cls.__name__)
        print(cls.name, cls.age, cls.money)

Computer.user_info()  # 类调用
'''
<class '__main__.Computer'>
Computer
痞老板 19119 90999
'''

注意 : 对象调用绑定给类的方法, 传入的还是这个对象对应的类

Computer().user_info()  # 对象调用 (输出结果还是一样)
'''
<class '__main__.Computer'>
Computer
痞老板 19119 90999
'''

二.非绑定方法

  • 在类的内部使用 @staticmethod 修饰的方法即为非绑定方法, 这类方法和普通的函数没有什么区别, 不与类或对象绑定
  • 谁都可以来调用, 且没有自动传值的效果, 那么为什么还要定义在类里面呢, 直接放在外面不就好了, 这是为了方便管理
import hashlib


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

    @staticmethod
    def passwd_encrypt(salt, passwd):
        mima = hashlib.md5(salt.encode("utf-8"))
        mima.update(passwd.encode("utf-8"))
        return mima.hexdigest()

🍖类调用
ciphertext = User.passwd_encrypt("haha", '123')
# 01ddae4032e17a1c338baac9c4322b30
print(User.passwd_encrypt)
# <function User.passwd_encrypt at 0x000001442FF1EEE8> 可以发现就是个普通函数

🍖对象调用
P1 = User("珊迪")
ciphertext2 = P1.passwd_encrypt("haha", '123')
# 01ddae4032e17a1c338baac9c4322b30
print(P1.passwd_encrypt)
# <function User.passwd_encrypt at 0x000001442FF1EEE8> 可以发现就是个普通函数

三.类的绑定方法应用示例

1.将文件里面的信息取出来实例成对象, 这个对象信息是已经存在的, 而不是新建的对象

  • 先模拟一个文件,存入信息
import pickle

with open("Duck.json","wb")as f:
    pickle.dump({"品种":"快跑鸭","大小":22,"颜色":"yellow"},f)
  • 再把信息拿出来, 通过类的绑定方法创建这个已有信息对象
import pickle

class Duck:
    def __init__(self,breed,size,color):
        self.breed = breed
        self.size = size
        self.color = color

    @classmethod
    def from_file(cls):
        return cls(Breed,Size,Color)

# 从文件里面拿出信息
with open("Duck.json","rb")as f1:
    duck_info = pickle.load(f1)

# 赋值给这些变量
Breed = duck_info["品种"]
Size = duck_info["大小"]
Color = duck_info["颜色"]

# 通过类来调用自己的方法
info = Duck.from_file()
print(info)  # <__main__.Duck object at 0x0000020ACF597A08>
print(info.breed)  # 快跑鸭
print(info.size)   # 22
print(info.color)  # yellow

四.小结

1.绑定方法小结

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

2.非绑定方法小结

  • 如果函数体代码既不需要外部传入的类也不需要外部传入的对象,则应该将该函数定义成非绑定方法/普通函数
posted @ 2020-12-27 11:46  给你骨质唱疏松  阅读(165)  评论(0编辑  收藏  举报