继承
ref
ref
继承可以重用已经存在的数据和行为,减少代码的重复编写,子类继承了父类的所有公有属性和方法。继承,实现了代码重用
子类拥有父类的所有属性和方法,如果子类想重写父类的方法,可以直接重写。
支持多重继承,当父类中出现多个自定义的__init__的方法时,多重继承,只执行第一个累的__init_方法,其他不执行。
如果想调用父类的 heshui 这个方法,可以用 super()
class Animal:
def heshui(self):
print('动物正在喝水')
class Cat(Animal):
def heshui(self):
super().heshui()
cat = Cat()
cat.heshui()
如果父类的方法是私有方法,如 def __heshui(self) 这样的话再去调用就提示没有这个方法,其实编译器是把这个方法的名字改成了 _Animal__heshui(),如果强制调用,可以这样:
class Animal:
def __heshui(self):
print('动物正在喝水')
class Cat(Animal):
def heshui(self):
super()._Animal__heshui()
cat = Cat()
cat.heshui()
如果父类定义了__init__方法,子类必须显式调用父类的__init__方法,
如果子类自己也定义了 init 方法,那么父类的属性是不能直接调用的,可以在 子类的 __init__中调用一下父类的 init 方法。(__init__中是可以加入初始化参数的)
class Animal:
def __init__(self):
self.a = 'aaa'
class Cat(Animal):
def __init__(self):
super(Cat, self).__init__() #也可以用 Animal.__init__(self) 这里面的self一定要加上
cat = Cat()
print(cat.a)
类的属性
类属性,也是公有属性,
类的私有属性,(多用_标识)
对象的共有属性,
对象的私有属性,
内置属性,
函数的局部变量,
全局变量
var6 = '全局变量 '
class MyClass(object):
var1 = '类属性,类的公有属性 var1' ##定义在方法外
__var2 = '类的私有属性 __var2'
def func1(self):
self.var3 = '对象的公有属性 var3' ##定义在方法内
self.__var4 = '对象的私有属性 __var4'
var5 = '函数的局部变量'
def func2(self):
print self.var1
print self.__var2
print self.var3
print self.__var4
print self.var6
mc = MyClass()
mc.func1()
mc.func2()
print '*'*50
print mc.__dict__
print MyClass.var1
#print MyClass.__var2 #不测通过类访问
print mc.var3 #对象的属性只能通过对象来访问
#print MyClass.__var4
print MyClass.__dict__
类的方法
公有方法
私有方法
类方法
静态方法
内置方法
class MyClass(object):
name = 'Test'
def func1(self):
print self.name,
print "我是公有方法."
self.__func2() #func1间接调用了func2的私有方法
def __func2(self):
print self.name,
print "我是私有方法."
def classFun(self):
print self.name,
print "我是类方法."
def staticFun(self):
print s.name,
print "我是静态方法."
mc = MyClass()
mc.func1()
@abstractmethod
抽象方法,含abstractmethod方法的类不能实例化,继承了含abstractmethod方法的子类必须复写所有abstractmethod装饰的方法,未被装饰的可以不重写,子类实现了该抽象方法才能被实例化。
class CameraBase():
def __init__(self, frame_info):
self.camera = None
@abstractmethod
def _connect_camera(self, cam_ip): # 一般抽象方法不实现
raise NotImplementedError # 多用raise
class CameraEpicEye(CameraBase):
def __init__(self, frame_info, **kwargs):
super(CameraEpicEye, self).__init__(frame_info)
def _connect_camera(self):
self.camera.connect()
@staticmethod
静态方法,可以通过实例对象和类对象调用,被装饰函数可无参数,被装饰函数内部通过类名.属性引用类属性或类方法,不能引用实例属性。静态方法多为和类相关,但是又不需要类和实例中的任何信息、属性等的方法
class C(object):
@staticmethod
def f():
print('runoob');
C.f(); # 静态方法无需实例化
cobj = C()
cobj.f() # 也可以实例化后调用
staticmethod 参数要求是 Callable, 也就是说 Class 也是可以的:
class C1(object):
@staticmethod
class C2(object):
def __init__(self, val = 1):
self.val = val
def shout(self):
print("Python世界第%d!"%self.val)
tmp = C1.C2(0)
print(type(tmp)) # 输出 : <class '__main__.C1.C2'>
tmp.shout() # 输出 : Python世界第0!
@classmethod
ref
类方法,可以通过实例对象和类对象调用,被该函数修饰的方法第一个参数代表类本身常用cls,被修饰函数内可调用类属性,不能调用实例属性
class A(object):
# 属性默认为类属性(可以给直接被类本身调用)
num = "类属性"
# 实例化方法(必须实例化类之后才能被调用)
def func1(self): # self : 表示实例化类后的地址id
print("func1")
print(self)
# 类方法(不需要实例化类就可以被类本身调用)
@classmethod
def func2(cls): # cls : 表示没用被实例化的类本身
print("func2")
print(cls)
print(cls.num)
cls().func1()
# 不传递传递默认self参数的方法(该方法也是可以直接被类调用的,但是这样做不标准)
def func3():
print("func3")
print(A.num) # 属性是可以直接用类本身调用的
# A.func1() 这样调用是会报错:因为func1()调用时需要默认传递实例化类后的地址id参数,如果不实例化类是无法调用的
A.func2()
A.func3()
由于Python不支持多个的參数重载构造函数,比方在C++里,构造函数能够依据參数个数不一样。能够写多个构造函数。Python为了解决问题,採用classmethod修饰符的方式,这样定义出来的函数就能够在类对象实例化之前调用这些函数,就相当于多个构造函数,解决多个构造函数的代码写在类外面的问题。
使用类方法的另一个好处就是在继承的时候,保证了子类使用可选构造函数构造出来的类是子类的实例而不是父类的实例。
property
@ property
方法伪装属性,方法返回值及属性值,被装饰方法不能有参数,必须实例化后调用,类不能调用。
@ property可以把一个实例方法变成其同名属性,以支持.号访问
class C(object):
def __init__(self):
self._x = None
@property # x变成可读属性
def x(self):
"""I'm the 'x' property."""
return self._x
@x.setter # 使得x属性变成可读可写属性
def x(self, value):
self._x = value
@x.deleter
def x(self):
del self._x
property函数
property函数有四个属性,分别是: fget, fset, fdel, doc, 分别对应取值方法,设置值方法和删除特性以及文档字符串。fdel和fdoc为可选类型。
class C(object):
def __init__(self):
self._x = None
def getx(self):
return self._x
def setx(self, value):
self._x = value
def delx(self):
del self._x
x = property(getx, setx, delx, "I'm the 'x' property.")