一 . 绑定方法与非绑定方法 :
类中定义函数分为两大类 :
1. 绑定方法 :
特殊之处 : 绑定给谁就应该由谁来调用, 谁来调用就会将谁当做第一个参数自动传入
绑定给对象的方法 :在类中定义函数没有被任何装饰器修饰的情况下,默认就是绑定对象的
绑定给类的方法 : 为类中定义函数添加一个装饰器classmethod, 就是绑定类的
2. 非绑定方法 :
特殊之处 : 非绑定方法就是一个普通的函数.
既不与类绑定又不与对象绑定意味着类与对象都可以调用,但是无论谁来调用都是一个普通
函数, 没有自动传值的效果.
非绑定方法 : 为类中定义函数添加一个装饰器,staticmethod.就是非绑定方法.
3. 两种方法的区别就是 : 是否会自动传值.
示例 :
class Foo:
def func1(self):
print('func1',self)
@classmethod
def func2(cls):
print('func2',cls)
@staticmethod
def func3(x,y):
print('func3',x,y)
obj = Foo()
# 绑定给对象的方法
# 绑定给对象的, 就应该由对象来调.
obj.func1()
print(obj)
# 绑定给对象的方法,类也可以调用,但是类调用就是一个普通函数,没有自动传值的效果
print(obj.func1)
print(Foo.func1)
Foo.func1(obj)
# 绑定给类的方法
# 绑定给类的,就应该由类来调用
print(Foo.func2)
print(obj.func2)
Foo.func2()
obj.func2()
# 非绑定方法.
print(obj.func3)
print(Foo.func3)
obj.func3(1.2)
Foo.func3(1.2)
示例:
#绑定 与 非绑定的使用场景示范
class MySQL:
def __init__(self,ip,port):
self.ip = ip # 参数写成self就等于写活了.谁都能调用
self.port = port
def tell_info(self):
print('%s:%s' %(self.ip , self.port))
@classmethod # 用配置文件里的数据, 可以把参数写成cls.用只给类名调用的装饰器来写
def from_conf(cls):
return cls(settings.IP, settings.PORT)
@staticmethod
def create_id(): # 不需要类名参数,也不需要对象参数, 就可以用这个装饰器来写, 不能不写
import uuid 参数, 不然会默认为参数是对象,就会报错.
return uuid.uuid4()
obj = MySQL('1.1.1.1',3306)
obj.tell_info()
总结 : 装饰器的使用是要看函数的代码是怎样的,需要什么用什么.
二 . 反射 :
反射指的是通过字符串来操作属性 :
示例:
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('egon' , 18)
# hasattr
print (hasattr(obj,(逗号)'name')) # 查看有没有这个属性 返回的是一个布尔值 等于 obj.name
# getattr
res = getattr(obj,'name') #获取一属性 等于 obj.name
# setattr
setattr(obj,'age',38) # 修改一个属性, 没有这个值就添加上这个值
# delattr
delattr(obj,'name') # 删除一个属性, 没有这个属性就报错
三. 面向对象高级内置方法 之 __str__ :
首先补充两个内置函数,
1. isinstance
print (isinstance([],list)) # 等于 type([]) is list
判断一个对象是否属于另一个类的对象.
2, issubclass
class Foo:
pass
class Bar(Foo):
pass
print(issubclass(Bar,Foo))
判断一个类是不是另一个类的子类
__str__ : 会在对象被打印时自动触发. 然后将返回值当做打印结果.
class People:
def __ init __ (self,name,age)
self.name = name
self.age = age
def __str__(self):
print('===>') #这里不能加self. 不然会无限递归下去,就会报错
return '<%s:%s>' %(slef.name,self.age)
peo = People('name',18)
print(peo) # 等于打印了 print(peo.__str__())
注意 : l = list([1,2,3])
print(l)
其实list 下面也有__str__的方法.不仅list.很多常用的内置函数都有
__del__: 会在对象被删除时自动触发执行, 用来在对象被删除前回收系统资源,
class Foo:
def __del__(self):
print('===>')
obj = Foo()
del obj
print('其他代码...')
__del__在什么时候使用?
示例:
class Bar:
def __init__(self,x,y,filepath)
self.x = x
self.y = y
self.f = open(filepath 'rt' , encoding = 'utf-8')
def __del__(self):
self.f.close() # 在del里写回收系统资源的代码
obj = Bar(10,20)
del obj
程序结束时会自动删除obj , obj的值也会被删除, 但是不会删除filepath 的数据. 这个时候就可以在类里
定义上 __del__的函数属性.