Python札记人工智能/模式识别/机器学习精华专题大数据,机器学习,人工智能

Python札记33_绑定方法和非绑定方法

2019-07-06  本文已影响1人  皮皮大

在类中除了属性还有方法,通常情况下通过实例来进行调用类的方法。本篇札记讲解四个方面进行:


非绑定方法 unbound method

通过类的名字直接来调用方法对象(函数对象),叫做非绑定方法。其中Foo是类,bar是类中的方法。类名字---->方法对象

image.png
class Foo:
    def bar(self):  # 第一个参数必须是self
        print("this is a method of class")
f = Foo()   # 调用类
f.bar()     # 调用类中方法(类中的函数也称之为方法)
this is a method of class
# 实例显式地传给方法
Foo.bar(f)  
this is a method of class

Foo.bar()  # 通过类直接调用方法,不传递参数报错,缺少self
image.png

绑定方法 bound method

绑定方法指的是通过实例得到方法对象的过程。实例---->方法对象

描述器

在类的属性中有个__dict__的特殊属性,用来查看内部信息:

Foo.__dict__["bar"]   # bar 是函数对象
image.png image.png

结果:描述器的返回结果和Foo.bar是相同的。其中self指定为None,表示没有给定实例。

Foo.__dict__["bar"].__get__(f, Foo) # 给定实例f;与实例得到方法对象结果相同
image.png

类方法

lass Foo:   # 定义一个类
    lang = 'Java'  # 定义类的属性lang = "java"
    def __init__(self):  # 初始化方法__init__
        self.lang = 'python' # 实例属性,self是实例对象,属性数lang = "python"
        
def get_class_attr(cls):  
    return cls.lang   # 引用的对象具有lang属性
    
if __name__ == "__main__":
    print("Foo.lang(类属性值)", Foo.lang)  # 输出类lang属性值
    r = get_class_attr(Foo)   # 调用get_class_attr()方法,其中参数Foo刚好有lang属性
    print("get class attr:", r)  
    f = Foo()  # 创建实例f
    print("instance attribute(实例属性值)", f.lang)  # 参数实例的lang属性值
    

结果:

Foo.lang(类属性值) Java
get class attr: Java
instance attribute(实例属性值) python

缺陷:

使用装饰器来解决上面的问题

class Foo:   # 定义一个类
    lang = 'Java'  # 定义类的属性lang = "java"
    def __init__(self):  # 初始化方法__init__
        self.lang = 'python' # 实例属性,self是实例对象,属性数lang = "python"
        
    # 修改部分,加上装饰器,@classmethod装饰的函数第一个参数不是self
    @classmethod
    def get_class_attr(cls):  
        return cls.lang   # 引用的对象具有lang属性
    
if __name__ == "__main__":
    print("Foo.lang(类属性值)", Foo.lang)  # 输出类lang属性值
    r = get_class_attr(Foo)   # 调用get_class_attr()方法,其中参数Foo刚好有lang属性
    print("get class attr:", r)  
    f = Foo()  # 创建实例f
    print("instance attribute(实例属性值):", f.lang)  # 参数实例的lang属性值
    print("instance get_class_attr:", f.get_class_attr())
Foo.lang(类属性值) Java
get class attr: Java
instance attribute(实例属性值): python
instance get_class_attr: Java

结果:通过实例和类执行get_class_attr()方法得到的结果都是Java

静态方法

下面是一个有待优化的代码,因为类Foo里面使用了外面定义的函数select函数,不便于维护

import random

def select(n):
    a = random.randint(0, 100)    # 生成一个随机数
    return a - n > 0

class Foo:
    def __init__(self, name):     # 初始化函数
        self.name = name    # 实例self的 name属性为name
        
    def get_name(self, age):    # 第一参数必须是self
        if select(age) is True:     #   就是返回值大于0
            return self.name   
        else:
            return "this name is secret."
    
if __name__ == "__main__":
    f = Foo("Peter")
    name = f.get_name(27)
    print(name)

优化代码如下

import random

class Foo:   # 定义类,首字母大写 
    def __init__(self, name):  # 初始化函数
        self.name = name   # self实例的name属性为name
    
    def get_name(self, age):   # 将原来在外面的函数放在里面
        if self.select(age):   # 直接通过实例进行调用;也可以通过类进行调用:Foo.select()
            return self.name   # 返回实例self的name属性值
        else:
            return "the name is secret"
        
   # 增加装饰器 
    @staticmethod
    def select(n):   # 虽然在类里面,但是第一个参数不是self
        a = random.randint(1,100)
        return a - n > 0
    
if __name__ == "__main__":
    f = Foo("luolaoshi")
    name = f.get_name(22)
    print(name)

小结:


下面对上面的四种方法进行一个小结:

上一篇 下一篇

猜你喜欢

热点阅读