目录
1. issubclass(class, classinfo)
2. isinstance(object, classinfo)
4. getattr(object, name[, default])
5. setattr(object, name, value)
7. property(fget=None, fset=None, fdel=None, doc=None)
判断 class 是否为 classinfo 的一个子类,是则返回 True,否则返回 False;
一个类可以认为是自身的子类;
一个类父类的父类或更高层级的父类,都可以认为是自身的父类;
class 必须为一个类对象,否则报错;classinfo 可以是类对象,也可以是类对象组成的元组,否则报错;
classinfo 为类对象元组时,class 只要是其中任意一个类对象的子类,则返回 True;
有多个父类的子类,只需要 classinfo 中有其中一个父类,则返回True;
- #创建父类
- class Base1:
- def __init__(self,name='Base1'):
- self.name1 = name
- def showname1(self):
- print(f'名字为:{self.name1}')
-
- class Base2:
- def __init__(self,name='Base2'):
- self.name2 = name
- def showname2(self):
- print(f'名字为:{self.name2}')
-
- class Base3:
- def __init__(self,name='Base3'):
- self.name3 = name
- def showname3(self):
- print(f'名字为:{self.name3}')
-
- #创建子类
- class Derived1(Base1):
- pass
-
- class Derived2(Base2,Base3):
- pass
-
- class Derived3(Derived1):
- pass
-
- #判断 class 是否为 classinfo 的一个子类,是则返回 True,否则返回 False
- issubclass(Derived1,Base1)
- True
- issubclass(Derived1,Base2)
- False
-
- #一个类可以认为是自身的子类
- issubclass(Derived1,Derived1)
- True
-
- #一个类父类的父类或更高层级的父类,都可以认为是自身的父类
- issubclass(Derived3,Base1)
- True
-
- #classinfo 可以类对象组成的元组,class 只要是其中任意一个类对象的子类,则返回 True
- issubclass(Derived1,(Base1,Base2))
- True
-
- #有多个父类的子类,只需要 classinfo 中有其中一个父类,则返回True
- issubclass(Derived2,Base2)
- True
- issubclass(Derived2,Base3)
- True
-
- #class 不是类对象报错
- issubclass((Derived1,Derived2),Base1)
- Traceback (most recent call last):
- File "<input>", line 1, in <module>
- TypeError: issubclass() arg 1 must be a class
- #classinfo 不是类对象或元组报错
- issubclass(Derived1,[Base1,Base2])
- Traceback (most recent call last):
- File "<input>", line 1, in <module>
- TypeError: issubclass() arg 2 must be a class or tuple of classes
判断 object 是否为 classinfo 的一个实例对象,是则返回 True,否则返回 False;
object 是 classinfo 中某个类对象的子类或更下层的子类的子类等,仍返回True;
object 必须为一个实例对象,否则返回 False;classinfo 可以是类对象,也可以是类对象组成的元组,否则报错;
classinfo 为类对象元组时,object 只要是其中任意一个类对象的实例对象,则返回 True;
- #创建的类见章节1. issubclass
- #创建实例对象
- base11 = Base1()
- base12 = Base1()
- base13 = Base1()
- base21 = Base2()
- derived11 = Derived1()
- derived12 = Derived1()
- derived21 = Derived2()
- derived31 = Derived3()
-
- #判断 object 是否为 classinfo 的一个实例对象,是则返回 True,否则返回 False
- isinstance(base11,Base1)
- True
- isinstance(base21,Base1)
- False
- isinstance(base12,Base1)
- True
-
- #object 是 classinfo 中某个类对象的子类或更下层的子类的子类等,仍返回True
- isinstance(derived11,Base1)
- True
- isinstance(derived21,Base1)
- False
- isinstance(derived31,Base1)
- True
- isinstance(derived21,Base2)
- True
- isinstance(derived21,Base3)
- True
-
- #classinfo 为类对象元组时,object 只要是其中任意一个类对象的实例对象,则返回 True
- isinstance(derived31,(Base1,Base3))
- True
-
- #class 必须为一个实例对象,否则返回 False
- isinstance(Base1,Base1)
- False
- isinstance(Derived1,Base1)
- False
- isinstance(derived11.name1,Base1)
- False
- isinstance(derived11.showname1,Base1)
- False
- #classinfo 可以是类对象,也可以是类对象组成的元组,否则报错
- isinstance(derived31,[Base1,Base3])
- Traceback (most recent call last):
- File "<input>", line 1, in <module>
- TypeError: isinstance() arg 2 must be a type or tuple of types
判断实例对象 object 中是否有属性名为 name 的变量或方法,是则返回 True,否则返回 False;
object 必须为一个实例对象,否则返回 False;
name 为变量或方法名的字符串,否则报错;
可以认为是将实例对象 object 及其类对象的 '__dict__' 属性中所有的键与 'name' 做比对,判断是否与其中一个键值相等。
- #创建的类见章节1. issubclass
- #创建实例对象见章节2. isinstance
-
- #实例对象与创建实例的类对象的 '__dict__' 属性
- base11.__dict__
- {'name1': 'Base1'}
- Base1.__dict__
- mappingproxy({'__module__': '__main__', '__init__': <function Base1.__init__ at 0x00000218364AB040>, 'showname1': <function Base1.showname1 at 0x00000218364AB160>, '__dict__': <attribute '__dict__' of 'Base1' objects>, '__weakref__': <attribute '__weakref__' of 'Base1' objects>, '__doc__': None})
-
- #判断实例对象 object 中是否有属性名为 name 的变量或方法,是则返回 True,否则返回 False
- hasattr(base11,'name1')
- True
- hasattr(base11,'showname1')
- True
- hasattr(base11,'__init__')
- True
- hasattr(base11,'__dict__')
- True
- hasattr(base11,'__doc__')
- True
-
- #object 为类对象,返回 False
- hasattr(Base1,'name1')
- False
- #name 不是字符串,报错
- hasattr(base11,name1)
- Traceback (most recent call last):
- File "<input>", line 1, in <module>
- NameError: name 'name1' is not defined
返回实例对象 object 中,属性名为 name 的变量或方法;
object 中不存在名为 name 的变量或方法,则default 可选参数已赋值返回 default 值,default 未赋值报错;
可以认为是将实例对象 object 及其类对象的 '__dict__' 属性中所有的键与 'name' 做比对,如有对应的键,返回该键相应的值。
- #创建的类见章节1. issubclass
- #创建实例对象见章节2. isinstance
-
- #返回实例对象 object 中,属性名为 name 的变量
- getattr(derived11,'name1')
- 'Base1'
-
- #返回实例对象 object 中,属性名为 name 的方法
- getattr(derived11,'showname1')
- <bound method Base1.showname1 of <__main__.Derived1 object at 0x00000218364A6370>>
- x = getattr(derived11,'showname1')
- x()
- 名字为:Base1
-
- #不存在名为 name 的变量或方法,则default 可选参数已赋值返回 default 值
- getattr(derived11,'name2','实例中没有该属性!')
- '实例中没有该属性!'
-
- #不存在名为 name 的变量或方法,default 未赋值报错
- getattr(derived11,'name2')
- Traceback (most recent call last):
- File "<input>", line 1, in <module>
- AttributeError: 'Derived1' object has no attribute 'name2'
设置实例对象 object 中,属性名为 name 的变量或方法的值为 value;
object 中不存在名为 name 的变量或方法,则新建变量或方法并赋值为 value;
可以认为是将实例对象 object 及其类对象的 '__dict__' 属性中所有的键与 'name' 做比对,如有对应的键,设置该键的值为 'value';没有对应的键,则新建键值对 'name : value';
该方法可设置类中变量,新设置类的方法则会因 self 参数或修饰符导致调用失败;
- #创建的类见章节1. issubclass
- #创建实例对象见章节2. isinstance
-
- #设置修改类中变量
- derived21.showname2()
- 名字为:Base2
- setattr(derived21,'name2','TEST')
- derived21.showname2()
- 名字为:TEST
- derived21.name2
- 'TEST'
-
- #设置类中不存在的变量,新增变量属性
- setattr(derived21,'nametest','nameTEST')
- derived21.nametest
- 'nameTEST'
-
- #设置修改类中方法为实例方法
- def shownametest2(self):
- print(derived21.nametest + '2')
-
- setattr(derived21,'showname2',shownametest2)
-
- #设置成功,调用失败报错
- shownametest2
- <function shownametest2 at 0x00000218364A84C0>
- derived21.__dict__
- {'name2': 'TEST', 'nametest': 'nameTEST', 'showname2': <function shownametest2 at 0x00000218364A84C0>}
- derived21.showname2()
- Traceback (most recent call last):
- File "<input>", line 1, in <module>
- TypeError: shownametest2() missing 1 required positional argument: 'self'
-
- #设置修改类中方法为静态方法,调用报错
- @staticmethod
- def shownametest():
- print(derived21.nametest)
-
- setattr(derived21,'showname2',shownametest)
- derived21.showname2()
- Traceback (most recent call last):
- File "<input>", line 1, in <module>
- TypeError: 'staticmethod' object is not callable
删除实例对象 object 中,属性名为 name 的变量或方法,如果变量或方法不存在,报错;
可以认为是将实例对象 object 及其类对象的 '__dict__' 属性中所有的键与 'name' 做比对,如有对应的键,删除该键值对,没有则报错;
无法删除不在实例对象 '__dict__' 中属于类对象的变量或方法。
- #创建类
- class Base:
- info = '123456'
- def __init__(self,name='Base'):
- self.name = name
- def showname(self):
- print(f'名字为:{self.name}')
-
- class Derived(Base):
- info = 'abcdef'
- def showname(self,name2):
- print(f'名字由:{self.name},变为:{name2}')
-
- #创建实例对象
- derived = Derived('Test')
- derived.showname('Test2')
- 名字由:Test,变为:Test2
- derived.info
- 'abcdef'
-
- #实例对象 '__dict__' 属性
- derived.__dict__
- {'name': 'Test'}
-
- #删除实例对象变量 name,删除后无法调用
- derived.name
- Traceback (most recent call last):
- File "<input>", line 1, in <module>
- AttributeError: 'Derived' object has no attribute 'name'
-
- #删除实例对象对应的类对象变量或方法,失败
- delattr(derived,'showname')
- Traceback (most recent call last):
- File "<input>", line 1, in <module>
- AttributeError: showname
- delattr(derived,'info')
- Traceback (most recent call last):
- File "<input>", line 1, in <module>
- AttributeError: info
- delattr(derived,'name')
property 返回一个类的属性 attribute,创建实例对象后,实例对象通过该属性调用赋值给 fget、fset、fdel 三个参数的方法,实现读取、设置、删除三种操作;
实例.attribute 将调用 getter,实现读取;
实例.attribute = value 将调用 setter,实现设置;
del 实例.attribute 将调用 deleter,实现删除;
当编码时,需要维护修改类中的读取、设置、删除方法时,只需要改变 property 中参数赋值的方法,调用 property 返回属性的其他代码无需改动。
- #创建类
- class Testproperty:
- def __init__(self,num):
- self.num = num
-
- def getnum(self):
- return self.num
-
- def setnum(self,value):
- self.num = value
-
- def delnum(self):
- del self.num
-
- #类中定义调用 property 函数的属性
- testattr = property(getnum, setnum, delnum, 'test property!')
-
- #创建实例,检查实例变量
- test = Testproperty(5)
- test.num
- 5
-
- #通过 property 返回属性 testattr 做读取
- test.testattr
- 5
- #通过 property 返回属性 testattr 做设置
- test.testattr = 10
- test.num
- 10
- #通过 property 返回属性 testattr 做删除
- del test.testattr
- test.num
- Traceback (most recent call last):
- File "<input>", line 1, in <module>
- AttributeError: 'Testproperty' object has no attribute 'num'
除了直接调用 property 函数,也可以通过 property 的修饰符实现同样的效果。
- #创建与章节7. property 相同效果的类
- class Testproperty:
- def __init__(self,num):
- self.num = num
-
- @property
- def testattr(self):
- '''test property!'''
- return self.num
-
- @testattr.setter
- def testattr(self,value):
- self.num = value
-
- @testattr.deleter
- def testattr(self):
- del self.num
-
- #执行读取、设置、删除,效果一致
- test = Testproperty(5)
- test.num
- 5
- test.testattr
- 5
- test.testattr = 10
- test.num
- 10
- del test.testattr
- test.num
- Traceback (most recent call last):
- File "<input>", line 1, in <module>
- AttributeError: 'Testproperty' object has no attribute 'num'