类的零碎知识点:classmethod / staticmethod / hasattr / getattr / setattr / delattr / __str__ / __del__
绑定方法与非绑定方法
一:绑定方法(绑定给谁,谁来调用就自动将它本身当作第一个参数传入):
- 绑定到类的方法:用classmethod装饰器装饰的方法。为类量身定制类.boud_method(),自动将类当作第一个参数传入(其实对象也可调用,但仍将类当作第一个参数传入)
- 绑定到对象的方法:没有被任何装饰器装饰的方法。为对象量身定制
对象.boud_method(),自动将对象当作第一个参数传入(属于类的函数,类可以调用,但是必须按照函数的规则来,没有自动传值那么一说)
二:非绑定方法:用staticmethod装饰器装饰的方法
- 不与类或对象绑定,类和对象都可以调用,但是没有自动传值那么一说。就是一个普通工具而已
注意:与绑定到对象方法区分开,在类中直接定义的函数,没有被任何装饰器装饰的,都是绑定到对象的方法,可不是普通函数,对象调用该方法会自动传值,而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__的作用就体现出来了。