継承:解決するためのコードを繰り返して、
#继承语法 class 子类名(父类名):pass class A: pass class B(A): pass # A 父类 基类 超类 # B子类 派生类
サブクラスは親クラスを使用することができますメソッドと静的変数
class Animal: def __init__(self,name): self.name = name def eat(self): print('%s is eating'%self.name) def drink(self): print('%s is drinking'%self.name) def sleep(self): print('%s is sleeping'%self.name) class Cat(Animal): def climb_tree(self): print('%s is climbing'%self.name) class Dog(Animal): def house_keep(self): print('%s house keeping'%self.name) 小白 = Cat('小白') # 先开辟空间,空间里有一个类指针-->指向Cat # 调用init,对象在自己的空间中找init没找到,到Cat类中找init也没找到, # 找父类Animal中的init 小白.eat()#小白 is eating 小白.climb_tree()#小白 is climbing 小黑 = Dog('小黑') 小黑.eat()#小黑 is eating
同じ名前の親クラスとサブクラスは、我々はサブクラスのためにのみ使用し、親クラスのメソッドを呼び出すことがないときは
class Animal: def __init__(self,name): self.name = name def eat(self): print('%s is eating'%self.name) def drink(self): print('%s is drinking'%self.name) def sleep(self): print('%s is sleeping'%self.name) class Cat(Animal): def eat(self): print('%s吃猫粮'%self.name) def climb_tree(self): print('%s is climbing'%self.name) 小白 = Cat('小白') 小白.eat()#小白吃猫粮
同時に、あなたはメソッドをサブクラス化したい親クラスが同じ名前の独自のメソッドを実装したいと思い呼び出します
メソッドのサブクラスで親クラスのメソッドを呼び出します。親クラスのメソッド名の名前(自己)
class Animal: def __init__(self,name,food): self.name = name self.food = food self.blood = 100 self.waise = 100 def eat(self): print('%s is eating %s'%(self.name,self.food)) def drink(self): print('%s is drinking'%self.name) def sleep(self): print('%s is sleeping'%self.name) class Cat(Animal): def eat(self): self.blood += 100 Animal.eat(self) def climb_tree(self): print('%s is climbing'%self.name) self.drink() class Dog(Animal): def eat(self): self.waise += 100 Animal.eat(self) def house_keep(self): print('%s is keeping the house'%self.name) 小白 = Cat('小白','猫粮') 小黑 = Dog('小黑','狗粮') 小白.eat()#小白 is eating 猫粮 小黑.eat()#小黑 is eating 狗粮 print(小白.__dict__)#{'name': '小白', 'food': '猫粮', 'blood': 200, 'waise': 100} print(小黑.__dict__)#{'name': '小黑', 'food': '狗粮', 'blood': 100, 'waise': 200} #父类和子类方法的选择: # 子类的对象,如果去调用方法 # 永远优先调用自己的 # 如果自己有 用自己的 # 自己没有 用父类的 # 如果自己有 还想用父类的 : 直接在子类方法中调父类的方法 父类名.方法名(self)
単一継承
# 单继承 # 调子类的 : 子类自己有的时候 # 调父类的 : 子类自己没有的时候 # 调子类和父类的 :子类父类都有,在子类中调用父类的 class D: def func(self): print('in D') class C(D):pass class A(C): def func(self): print('in A') class B(A):pass B().func()
多重継承
- Javaは多重継承をサポートしていないなど、いくつかの言語があります。
- 特長のPython言語:あなたがオブジェクト指向で多重継承をサポートすることができます
# 多继承 # 一个类有多个父类,在调用父类方法的时候,按照继承顺序,先继承的就先寻找 class D: def func(self): print('in D') class C(D):pass class A(C): def func(self): print('in A') class B(A):pass B().func()
オブジェクトクラスのクラス父親
すべてのクラスはのpython3オブジェクトクラスの中で継承されています
class A:pass print(A.__bases__)#(<class 'object'>,) class C:pass class B(A,C):pass print(B.__bases__)#(<class '__main__.A'>, <class '__main__.C'>)只能找到父类 不能找到父类的父类
バウンド方法と共通機能
from types import FunctionType,MethodType # FunctionType : 函数 # MethodType : 方法 class A: def func(self): print('in func') print(A.func) # 函数 #<function A.func at 0x000002841C479488> a = A() print(a.func) # 方法 #<bound method A.func of <__main__.A object at 0x000002841C308240>> print(isinstance(a.func,FunctionType))#False print(isinstance(a.func,MethodType))#True print(isinstance(A.func,FunctionType))#True print(isinstance(A.func,MethodType))#False #类.func是函数 #对象.func是方法
pickelシリアライズ可能なオブジェクト
前提PYファイル、クラスのオブジェクトがあります
class Course: def __init__(self,name,period,price): self.name = name self.period = period self.price = price python = Course('python','6 moneth',21800) linux = Course('linux','5 moneth',19800) go = Course('go','4 moneth',12800) import pickle with open('pickle_file','ab') as f: pickle.dump(linux,f) pickle.dump(go,f) with open('pickle_file','rb') as f: while True: try: obj = pickle.load(f) print(obj.name,obj.period) except EOFError: break
高度な継承
クラスの継承
多重継承
- オブジェクトのクラスを継承する新しいクラス限り
- オブジェクトクラスを継承していますクラシック
すべてのクラスは、オブジェクトクラスを継承するのpython3では、彼らは新しいクラスです
Python2は、古典的なクラスで、継承オブジェクトクラスは新しいクラスであるクラスのオブジェクトを継承しません
クラシック:PY3には存在しませんが、クラスのPY2継承されたオブジェクトにはアクティブではありません
在py2中
class A:pass #经典类
class B(object):pass#新式类
在py3中
class A: #pass #新式类
class B(object):pass #新式类
単一継承で(それは新しいクラスであるか、クラシックが同じであるかどうか)
class A:
def func(self):pass
class B(A):
def func(self):pass
class C(B):
def func(self):pass
class D(c):
def func(self):pass
d = D()
寻找某一个方法的顺序:D->C->B->A
越往父类走,是深度
多重継承
class A:
def func(self):
print('A')
class B(A):
def func(self):
print('B')
class C(A):
def func(Self):
print(C)
class D(B,C):
def func(self):
print('B')
print(D.mro()) #只在新式类中有,经典类没有
d = D()
d.func()
在走到一个点,下一个点既可以深度走,也可以从广度走的时候,总是先走广度,再走深度,广度优先
在经典类总,都是深度优先,总是在一条路走不通之后再换一条路,走过的点不会再走了
C3アルゴリズム
アルゴリズムの内容:
- あなたが単一継承している場合ので、必ずサブクラスに従ってください - 親クラスの検索順序の>順序を計算します
- 多重継承はこのクラス、親クラスの継承のため、後継親2の順序に従うように彼らの必要がある場合
- マージルール:クラスは、一番左に出現の右の順にクラスまたは左に提案されたように、ほとんどすべての左側に左から右へ、連続の一次、その後、別の場所に表示されませんでしたから順に表示された場合連続の順序で最初に提示するように側は、別の順序で表示されませんでした
- 最初の後に最初に現れるの左から右へ、そして、それを抽出することはできませんされていないからシーケンスの最初のカテゴリは、シーケンスが条件上記の他の親クラスを見つけるために後方に続く場合
- スーパー - (メソッドの関係MRO)に合わせて見つけるMROため、現在のクラスの親のために
python3での現在のクラスのクラスMRO順と同じ名前で自動的に方法を見つける私たちを助けるためにパラメータを渡す必要はありません。
中python2の新しいクラスが、我々はパラメータスーパー(合格するためのイニシアチブを取る必要があるオブジェクトのサブクラス名およびサブクラス)。関数名を()のこのサブクラスの次のクラスMRE順に呼び出すために、それは私たちを助けることができるように、方法
python2古典的なクラスでは、スーパーの使用は次のクラスに来てサポートしていません。
class A(object): def func(self):print('A') class B(A): def func(self): super().func() print('B') class C(A): def func(self): super().func() print('C') class D(B,C): def func(self): super().func() print('D') D().func() ''' A C B D '''
前記スーパー()。funcが()も書き込むことができ、スーパー(D、セルフ).FUNC() 。
単一継承の手順では、スーパーは、親クラスを見つけることです。
class User: def __init__(self,name): self.name = name class VIPUser(User): def __init__(self,name,level,strat_date,end_date): # User.__init__(self,name) # super().__init__(name) # 推荐的 # super(VIPUser,self).__init__(name) self.level = level self.strat_date = strat_date self.end_date = end_date ''' 解析:中间的# 的三种方式功能都是找到并执行父类中的__init__的方法,推荐使用 super().__init__(name)。 '''
先找每个类的继承关系(注意因为加载顺序的缘故从,上至下开始寻找) A(0) = [AO] # A 继承于object类 B(A) = [BAO] # B继承于A类 C(A) = [CAO] # C继承于A类 D(B) = [DBAO] # D继承于B类 E(C) = [ECAO] # E继承于C类 那么算法为: F(D,E) = merge(D(B)+E(C)) = [F] + [DBAO] + [ECAO] F = [DBAO] + [ECAO] FD = [BAO] + [ECAO] FDB = [AO] + [ECAO] FDBE = [AO] + [CAO] FDBEC = [AO] + [AO] FDBECAO - **使用子类名.mro() 查看继承顺序** 只有新式类中有,经典类没有的。
- 継承クラスを通じて開発仕様
制約の親サブクラス
一般的なカテゴリクラスABCなど
抽象クラス
- 彼の方法のすべてのサブクラスに結合、仕様の開発であり、彼の同名を実装する必要があります
はじめに:例:別のお支払い方法
class Wechat(): def __init__(self,name): self.name = name def pay(self,money): print('%s通过微信支付%s钱成功'%(self.name,money)) class Alipay(): def __init__(self,name): self.name = name def pay(self,money): print('%s通过微信支付%s钱成功'%(self.name,money)) class Apple(Payment): def __init__(self,name): self.name = name def pay(self,money): dic = {'name': self.name, 'number': money} # 想办法调用苹果支付 url连接 把dic传过去 print('%s通过苹果支付%s钱成功' % (self.name, money)) aw = WeChat('alex') aw.pay(400) aa = Alipay('alex') aa.pay(400) ''' 这样我们通过创建了2个对象,然后调用类中的方法pay,把钱传入完成支付的功能 '''
もちろん、我々は時々デザインを正規化する必要があります。
def pay(name,price,kind): if kind == 'Wechat': obj = WeChat(name) elif kind == 'Alipay': obj = Alipay(name) elif kind == 'Apple': obj = Apple(name) obj.pay(price) pay('alex',400,'Wechat') pay('alex',400,'Alipay') pay('alex',400,'Apple') ''' 我们通过定义一个函数,通过判别传入的kind参数,选择创建实例化name对象,然后调用方法,完成付款。 '''
注意: 3クラスのメソッド名を支払う必要が上記の要件を完了するために、エラーが報告されているかのように同じではありません。
上記の問題解決するために導入された抽象クラスのサブクラスに関連する制約を
class Payment: def pay(self,money): raise NotImplementedError('请在子类中重写同名pay方法') class Alipay(Payment):pass class WeChat(Payment):pass class Apple(Payment): pass def pay(name,price,kind): if kind == 'Wechat': obj = WeChat(name) elif kind == 'Alipay': obj = Alipay(name) elif kind == 'Apple': obj = Apple(name) obj.pay(price) ''' 解析:我们创建一个所有类的父类,定义一个pay的方法,如果执行,则抛出异常。 当我们执行pay函数时,我们会调用方法 pay ,当对象中没有pay的方法时,就会去父类Payment中调用,所以抛出异常。所以加入抽象类约束我们子类中方法名称一致。 ''' # 另一种方式:依赖于abc 模块 from abc import ABCMeta,abstractmethod class Payment(metaclass=ABCMeta): @abstractmethod def pay(self,money): '''只要你见到了项目中有这种类,你要知道你的子类中必须实现和pay同名的方法''' raise NotImplementedError('请在子类中重写同名pay方法') # 一旦子类中没有pay方法,实例化都无法完成。 方式特点:约束力强。缺点:依赖于abc模块
ポリモーフィズム
どこでもPythonは多型である、すべてが対象です
javaは説明して、多型は何ですか
状態の様々なアウトパフォーマンスの種類
Javaでは:パラメータが型を指定する必要がありますので、あなたは、オブジェクトの両方のタイプを渡すことができますしたい場合、あなたは、多分クラスは親クラスから継承させる時間の種類を指定して、指定した親クラスを使用する必要があります。
アヒルタイプ
class list: def __len__(self):pass class dict: def __len__(self): pass class set: def __len__(self): pass class tuple: def __len__(self): pass class str: def __len__(self): pass def len(obj): return obj.__len__() # 如上述所有实现了__len__方法的类,在调用len函数的时候,obj都说是鸭子类型。 # 再如:迭代器协议 __iter__ __next__ 是迭代器。即所有的迭代器都是鸭子类型