今天继续学习类。
超类
要指定超类,我们可以在class语句的类名后加上超类名,并用括号括起来。
class Person:
def pub(self):
return "Hello"
def ret(self):
return "1"+self.pub()
class Person2(Person):
def pub(self):
return "Hi"
a=Person2()
print(a.ret())
子类可以继承超类的功能。
再谈继承
要确定一个类是否为另一个类的子类,可使用issubclass。想确定一个对象是否为一个类的实例可使用isinstance。如果想获取对象属于哪个类,可以使用class。
class Person:
def pub(self):
return "Hello"
def ret(self):
return "1"+self.pub()
class Person2(Person):
def pub(self):
return "Hi"
a=Person2()
print(issubclass(Person2,Person),isinstance(a,Person),isinstance(a,Person2),a.__class__)
多个超类
我们创建的子类中可以包含多个超类,这个成为多重继承。但要使用要多加小心,前面的超类会遮盖后面的超类。
接口和内省
有时我们需要检查方法是否存在。
class Person:
def pub(self):
return "Hello"
def ret(self):
return "1"+self.pub()
class Person2(Person):
def pub(self):
return "Hi"
a=Person2()
print(hasattr(a,"ret"),hasattr(a,"rett")) # 检查属性是否存在
print(callable(getattr(a,"ret",None)),callable(getattr(a,"rett",None))) #检查属性是否可调用,None为属性不存在时使用的默认值。
setattr与getattr功能相反,可用于设置对象的属性。setattr(a,”ret”,rett)
class Person:
def pub(self):
return "Hello"
def ret(self):
return "1"+self.pub()
class Person2(Person):
def pub(self):
return "Hi"
a=Person2()
setattr(a,"ret","rett")
print(a.ret)
要查看对象中储存的所有值,可以检查dict属性。如果要确定对象是由什么组成的,应研究模块inspect,模块将在后面学习。
抽象基类
抽象基类是不能实例化的类,通过引入预置超类ABC实现。抽象类的继承类必须具有抽象基类指定的方法,所以常用于编写接口。
import abc
class Person(abc.ABC):
@abc.abstractclassmethod #装饰器,后续学习中会深入,目前知道用于标记此类为抽象即可
def pub(self):
pass
class Person2(Person):
def pub(self):
return "Hi"
class Person3:
pass
#a=Person() #此语句会报错,因为抽象类不能实例化
a=Person2() #重新编写后才可以实例化
b=Person3()
Person.register(Person3) #把Person3注册为Person,所有的Person3对象都将被视为Person对象
print(isinstance(b,Person),issubclass(Person3,Person))
b.pub() #但使用此法注册将失去抽象类的性质
我们可以阅读标准库参考手册查看更多关于模块abc的信息。