11.8到底什么是绑定?
Python严格要求方法需要有实例才能被调用,这种限制其实就是Python所谓的绑定概念。
class C:
count=0
def GetCount(self):
print("wo lai shushu?")
C.count=100
print(C.count())
--------------------
100
=====================但是,修改代码后
print(C.GetCount())
-----------------------
报错 TypeError: GetCount() missing 1 required positional argument: 'self'
=========================================================================
class BB:
def printBB( ):
print("no zuo no die")
print(BB.printBB())
-----------------------
no zuo no die
能够调用成功,但是会出现问题,实例化后的对象根本无法调用函数。
bb=BB()
print(bb.printBB())
-----------------------
TypeError: printBB() takes 0 positional arguments but 1 was given
根据绑定机制,这里会自动把bb对象作为第一个参数传入,所以出现了错误。
为了便于理解,再次深挖:
class CC:
def setXY(self,x,y):
self.x=x
self.y=y
def printXY(self):
print(self.x,self.y)
dd=CC()
==================================可以用__dict__看对象拥有的属性
print(dd.__dict__)
print(CC.__dict__)
-------------------
{}
{'__module__': '__main__', 'setXY': <function CC.setXY at 0x000001E3B2D89D90>,
'printXY': <function CC.printXY at 0x000001E3B2D89E18>, '__dict__': <attribute
'__dict__' of 'CC' objects>, '__weakref__': <attribute '__weakref__' of 'CC' o
bjects>, '__doc__': None}
==================================================================
dd.setXY(4,5)
print(dd.__dict__)
--------------------
{'x': 4, 'y': 5}
====================现在实例对象有了2个新属性,且仅仅属于实例对象
print(CC.__dict__) #依旧没有x=4 y=5
----------------------
{'__module__': '__main__', 'setXY': <function CC.setXY at 0x000001E3B2D89D90>,
'printXY': <function CC.printXY at 0x000001E3B2D89E18>, '__dict__': <attribute
'__dict__' of 'CC' objects>, '__weakref__': <attribute '__weakref__' of 'CC' o
bjects>, '__doc__': None}
==================================归功于self参数,实例对象dd调用setXY方法的
时候,传入的第一个参数就是dd.
进一步思考,如果把类实例删除掉,实例对象dd还能否调用printXY方法?
del CC
dd.printXY()
------------
4 5 # 答案是:可以的!
==========================================================
11.9一些相关的BIF 与类和对象有关的内置函数
1. issubclass(class,classinfo) 第一个是第二个的子类,则返回True
1)一个类认为是自身的子类
2)classinfo可以是类对象组成的元组,只要class是其中任何一个候选类的子类,则True
3)在其它情况下,会抛出一个TypeError异常
代码如下:
class A:
pass
class B(A):
pass
print(issubclass(B,A))
print(issubclass(B,B))
print(issubclass(B,object))
class C:
pass
print(issubclass(B,C))
-------------------------
True
True
True
False
===========================================
2.isinstance(object,classinfo) 第一个是第二个的实例对象,返回True
1)object是classinfo的子类的一个实例,也符合条件
2)第一个不是对象,则永远返回False
3)classinfo可以是类对象组成的元组,只要object是其中任何一个候选对象的实例,
都返回True
4)如果第二个参数不是类或者由类对象组成的元组,会抛出一个TypeError异常
class A:
pass
class B(A):
pass
class C:
pass
print(issubclass(B,C))
b1=B()
print(isinstance(b1,B))
print(isinstance(b1,C))
print(isinstance(b1,A))
print(isinstance(b1,(A,B,C)))
--------------------------------
False
True
False
True
True
============================================
3.hasattr(object,name) 和对象属性(attr)有关 测试对象是否有此属性
第一个是对象,第二个参数是属性名,举例如下:
class C:
def __init__(self,x=0):
self.x=x
c1=C()
print(hasattr(c1,"x")) #属性名要用引号括起来
---------------------
True
=================================================
4.getattr(object,name[,default]) 返回对象指定的属性值
若不存在,返回default的值,若没有指定参数,抛出异常。
class C:
def __init__(self,x=0):
self.x=x
c1=C()
print(getattr(c1,"x"))
-----------------------
0
========================
print(getattr(c1,"y"))
--------------------------
抛出异常
==========================
print(getattr(c1,"y","您访问的属性不存在。。。"))
-------------------------------------------------
您访问的属性不存在。。。
5.setattr(object,name,value) 可以设置对象指定属性的值,如果指定的属性不存在,
则新建并且赋值。
setattr(c1,"y","daodantou")
print(getattr(c1,"y"))
----------------------
daodantou
=================================
6.delattr(object,name) 用于删除对象中的指定属性,如果不存在,抛出异常。
delattr(c1,"y")
delattr(c1,"z")
--------------------------
第二局 抛出异常。
7.property(fget=None,fset=None,fdel=None,doc=None)
俗话说,条条大路通罗马,完成一件事,Python提供了好几个方法选择。
property()是一个比较奇葩的BIF,作用是通过属性来设置属性,有点绕,看代码:
class C:
def __init__(self,size=10):
self.size=size
def getSize(self):
return self.size
def setSize(self,value):
self.size=value
def delSize(self):
del self.size
x=property(getSize,setSize,delSize)
c=C()
print(c.x) 10
c.x=12
print(c.x) 12
print(c.size) 12
del c.x
print(c.size) 报错
======================================= x 起到了一个汇总作用,
哪一天需要修改类里面的方法名字,只需要同时改property里的,对外面不构成影响。