欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

类的零碎知识点:classmethod / staticmethod / hasattr / getattr / setattr / delattr / __str__ / __del__

程序员文章站 2022-03-08 19:27:03
...

绑定方法与非绑定方法

一:绑定方法(绑定给谁,谁来调用就自动将它本身当作第一个参数传入):

  1. 绑定到类的方法:用classmethod装饰器装饰的方法。为类量身定制类.boud_method(),自动将类当作第一个参数传入(其实对象也可调用,但仍将类当作第一个参数传入)
  2. 绑定到对象的方法:没有被任何装饰器装饰的方法。为对象量身定制
    对象.boud_method(),自动将对象当作第一个参数传入(属于类的函数,类可以调用,但是必须按照函数的规则来,没有自动传值那么一说)

二:非绑定方法:用staticmethod装饰器装饰的方法

  1. 不与类或对象绑定,类和对象都可以调用,但是没有自动传值那么一说。就是一个普通工具而已
    注意:与绑定到对象方法区分开,在类中直接定义的函数,没有被任何装饰器装饰的,都是绑定到对象的方法,可不是普通函数,对象调用该方法会自动传值,而staticmethod装饰的方法,不管谁来调用,都没有自动传值一说

绑定方法(classmethod)

前面我们学的类,定义一个函数,会默认作为对象的绑定方法,那么现在我有需求了,我需要在类内部定义一个函数,该函数需要绑定到类上,这该如何实现呢?
绑定给类的方法(classmethod)
classmehtod是给类用的,即绑定到类,类在使用时会将类本身当做参数传给类方法的第一个参数(即便是对象来调用也会将类当作第一个参数传入),python为我们内置了函数classmethod来把类中的函数定义成类方法
应用场景
我们想要在类内部生成对象时使用
例:

import settings

class MySQL:
    def __init__(self,ip,port):
        self.id=self.create_id()
        self.ip=ip
        self.port=port

    def tell_info(self):
        print('<%s:%s:%s>' % (self.id,self.ip, self.port))

    @classmethod     # 将函数装饰为绑定到类的方法
    def from_conf(cls):   # 只要调用这个方法,就可以实例化一个对象
        return cls(settings.IP, settings.PORT)

非绑定方法(staticmethod)

在类内部用staticmethod装饰的函数即非绑定方法,就是普通函数statimethod不与类或对象绑定,谁都可以调用,没有自动传值效果
当我有这么一种需求就要求类内部定义一个普通函数的时候,就可以用到staticmethod装饰器。


关于attr的几个内置函数(反射)

反射指的是通过字符串来操作属性

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

    def tell_info(self):
        print('%s:%s' %(self.name,self.age))

obj=Foo('Catalog Spri',18)
  • hasattr
print(hasattr(obj,'name')) # 相当于查看是否有obj.name这个属性,返回布尔值
print(hasattr(obj,'tell_info')) 

hasattr接收两个参数,第一个参数需要传入一个对象,第二个参数需要传入一个字符串,该函数会解析字符串内部的内容,然后判断传入的对象是否拥有字符串内部内容这个属性,具体看上面例子中的注释
参数一定要为字符串!!!
用来判断传入的对象是否有后面字符串的属性

  • getattr
res=getattr(obj,'name') #res=obj.name
print(res)
res=getattr(obj,'xxx',None)
print(res)

getattr的作用是获取对象下的一个属性。getattr接收三个参数,第一个参数为对象,第二个参数为一个字符串,第三个参数为default。前两个参数和hasattr的参数使用方式一样,重点说一下第三个参数。当default=None时,当你要获取的属性不存在时,返回值为None,而不设置default的情况下,当你要获取的属性不存在时,会抛出异常。

  • setattr
setattr(obj,'age',38)
setattr(obj,'sex','male')
print(obj.__dict__)
print(obj.sex)

创建一个新的属性或者修改一个原有的属性。
参数使用参照上面

  • delattr
delattr(obj,'name')

删除一个属性,当属性不存在的时候,抛出异常


类的两个内置方法

  • __str__: 会在对象被打印时( print(obj) )自动触发,然后将返回值返回给print功能进行打印
class People:
    def __init__(self,name,age):
        self.name=name
        self.age=age

    def __str__(self):
        return '<%s:%s>' %(self.name,self.age)

peo=People('Catalog Spri',18)
print(peo) #print(peo.__str__())

l=list([1,2,3])
print(l)

如果不设置__str__,会返回默认的值<main.People object at 0x103293978>

  • __del__: 会在对象被删除时自动触发执行,用来在对象被删除前回收系统资源
class Bar:
    def __init__(self,x,y,filepath):
        self.x=x
        self.y=y
        self.f=open(filepath,'r',encoding='utf-8')
    def __del__(self):
        # 写回收系统资源相关的代码
        self.f.close()

obj=Bar(10,20)
del obj

如果我们在代码中打开一个文件,会占用两部分资源,一部分是内存资源,一部分是系统资源。内存资源在程序结束时自动回收,但是系统资源不会自动回收。这时__del__的作用就体现出来了。

相关标签: