8パッケージ

7003 ワード

リード
パッケージ自体の意味から理解すると、パッケージは麻袋を持ってきて、子猫、子犬、王八、そしてalexを一緒に麻袋に入れて、麻袋を口に閉じ込めたようです.この論理から見ると,パッケージ=「隠す」という理解はかなり一面的である.
まず隠す方法を見て
pythonでプロパティを二重下線で隠す(プライベートに設定)
#             
#              __x       :_  __x   :

class A:
    __N=0 #             ,                      __N,    _A__N
    def __init__(self):
        self.__X=10 #   self._A__X
    def __foo(self): #   _A__foo
        print('from A')
    def bar(self):
        self.__foo() #           __foo      .

#A._A__N       ,                    ,              

この自動変形の特徴:
  • クラスで定義された_xはself._のような内部でのみ使用できます.x,参照するのは変形の結果である.
  • このような変形は、実は外部に対する変形であり、外部では通過できない_xという名前でアクセスしました.
  • サブクラスで定義された_xは親定義の__を上書きしません.xは、サブクラスに形成されているため:サブクラス名_xは、親によって形成されます:親クラス名_x,すなわち,二重スライド線の先頭の属性は,サブクラスに継承されるとサブクラスは上書きできない.

  • この変形に注意しなければならない問題は、
    1、このメカニズムは、外部から直接属性にアクセスすることを制限するものではありません.クラス名と属性名を知っていれば、名前をつづることができます.クラス名_プロパティを選択すると、a._などのアクセスが可能になります.A__N
    2、変形のプロセスはクラスの定義が一度だけ発生し、定義後の付与操作では変形しない
    3、継承では、親が子に自分のメソッドを上書きさせたくない場合は、メソッドをプライベートとして定義できます.
    #    
    >>> class A:
    ...     def fa(self):
    ...         print('from A')
    ...     def test(self):
    ...         self.fa()
    ... 
    >>> class B(A):
    ...     def fa(self):
    ...         print('from B')
    ... 
    >>> b=B()
    >>> b.test()
    from B
    
    
    # fa      , __fa
    >>> class A:
    ...     def __fa(self): #        _A__fa
    ...         print('from A')
    ...     def test(self):
    ...         self.__fa() #           ,   _A__fa
    ... 
    >>> class B(A):
    ...     def __fa(self):
    ...         print('from B')
    ... 
    >>> b=B()
    >>> b.test()
    from A

    パッケージは単なる意味の隠れではない
    1:データのカプセル化
    データを隠すのは目的ではありません.非表示にしてデータを操作するインタフェースを外部に提供し、インタフェースにデータ操作の制限を追加して、データ属性操作の厳格な制御を完了することができます.
    class Teacher:
        def __init__(self,name,age):
            self.__name=name
            self.__age=age
    
        def tell_info(self):
            print('  :%s,  :%s' %(self.__name,self.__age))
        def set_info(self,name,age):
            if not isinstance(name,str):
                raise TypeError('          ')
            if not isinstance(age,int):
                raise TypeError('       ')
            self.__name=name
            self.__age=age
    
    t=Teacher('egon',18)
    t.tell_info()
    
    t.set_info('egon',19)
    t.tell_info()

    2:パッケージ方法:複雑さを隔離することを目的とする
    #     ,            :  、    、    、    、  
    #      ,             ,             ,      
    #      ,         
    
    class ATM:
        def __card(self):
            print('  ')
        def __auth(self):
            print('    ')
        def __input(self):
            print('      ')
        def __print_bill(self):
            print('    ')
        def __take_money(self):
            print('  ')
    
        def withdraw(self):
            self.__card()
            self.__auth()
            self.__input()
            self.__print_bill()
            self.__take_money()
    
    a=ATM()
    a.withdraw()

    パッケージング方法の他の例:
  • あなたの体はカプセル化の概念を体現していないところはありません:あなたの体は膀胱の尿道などのこれらの尿の機能を隠して、それからあなたのために尿のインターフェースを提供して(インターフェースはあなたのです...,)、あなたはいつも膀胱を体の外に掛けて、トイレに行く時他の人に自慢することができません:hi、man、あなたは私の膀胱を見て、私がどのように尿をしたかを見てください.
  • テレビ自体は黒い箱で、すべての細部を隠していますが、必ず外部にボタンを提供しています.これらのボタンもインタフェースの概念なので、パッケージは単純な意味の隠しではありません!!
  • シャッターはバカカメラがバカたちに提供する方法で、内部の複雑な写真機能を
  • に隠している.
    ヒント:プログラミング言語では、対外的に提供されるインタフェース(インタフェースは1つのインタフェースとして理解できる)は、インタフェース関数と呼ばれ、インタフェース関数と呼ばれます.これはインタフェースの概念とは異なり、インタフェースはインタフェース関数の集合体を表しています.
    プロパティ(property)
    プロパティとは
    propertyは特殊な属性で、アクセス時に機能(関数)を実行して値を返します.
    例1:BMI指数(bmiは計算されたが、方法ではなく属性のように聞こえるのは明らかで、属性を1つにすれば理解しやすい)
    大人のBMI数値:
    軽量化:18.5未満
    正常:18.5-23.9
    重量オーバー:24-27
    肥満:28-32
    非常に肥満で32より高い
    体質指数(BMI)=体重(kg)÷身長^2(m)
    EX:70kg÷(1.75×1.75)=22.86
    class People:
        def __init__(self,name,weight,height):
            self.name=name
            self.weight=weight
            self.height=height
        @property
        def bmi(self):
            return self.weight / (self.height**2)
    
    p1=People('egon',75,1.85)
    print(p1.bmi)

    例2:円の周長と面積
    import math
    class Circle:
        def __init__(self,radius): #    radius
            self.radius=radius
    
        @property
        def area(self):
            return math.pi * self.radius**2 #    
    
        @property
        def perimeter(self):
            return 2*math.pi*self.radius #    
    
    c=Circle(10)
    print(c.radius)
    print(c.area) #              area,          ,        
    print(c.perimeter) #  
    '''
        :
    314.1592653589793
    62.83185307179586
    '''

    注意:この場合のプロパティareaとperimeterは付与できません.
    c.area=3 #   area  
    '''
        :
    AttributeError: can't set attribute
    '''

    なぜpropertyを使うのか
    1つのクラスの関数を特性として定義後、オブジェクトが再使用されるときobj.name,自分のnameが関数を実行して計算されたことにまったく気づかない,この特性の使い方は統一アクセスの原則に従っている
    それ以外は
    ps:            :
    【public】
             ,      
    【protected】
               ,    (friend)    (      “  ”,             “  ”,  “parent”   “  ”   ,      “  ”)  
    【private】
              

    pythonは文法的に3つの内部を独自のclassメカニズムに構築していません.C++では一般的にすべてのデータをプライベートに設定し、setとgetメソッド(インタフェース)を提供して設定し、取得します.pythonではpropertyメソッドで実現できます.
    class Foo:
        def __init__(self,val):
            self.__NAME=val #             
    
        @property
        def name(self):
            return self.__NAME #obj.name    self.__NAME(           )
    
        @name.setter
        def name(self,value):
            if not isinstance(value,str):  #            
                raise TypeError('%s must be str' %value)
            self.__NAME=value #       ,  value        self.__NAME
    
        @name.deleter
        def name(self):
            raise TypeError('Can not delete')
    
    f=Foo('egon')
    print(f.name)
    # f.name=10 #    'TypeError: 10 must be str'
    del f.name #    'TypeError: Can not delete'

    パッケージと拡張性
    パッケージは、外部呼び出し者のコードに影響を与えることなく、クラス実装者がパッケージ内のものを修正できるように、内外を明確に区別することにある.外部使用者は1つのインタフェース(関数)しか知らず、インタフェース(関数)名、パラメータが変わらない限り、使用者のコードは永遠に変更する必要はありません.これにより、インタフェースという基本的な約束が変わらない限り、コードの変更は心配できないという良好な協力基盤が提供されます.
    #     
    class Room:
        def __init__(self,name,owner,width,length,high):
            self.name=name
            self.owner=owner
            self.__width=width
            self.__length=length
            self.__high=high
        def tell_area(self): #       ,          ,          
            return self.__width * self.__length
    
    
    #   
    >>> r1=Room('  ','egon',20,20,20)
    >>> r1.tell_area() #       tell_area
    
    
    #     ,        ,                  
    class Room:
        def __init__(self,name,owner,width,length,high):
            self.name=name
            self.owner=owner
            self.__width=width
            self.__length=length
            self.__high=high
        def tell_area(self): #       ,      ,          ,      ,                  ,          ,       ,        
            return self.__width * self.__length * self.__high
    
    
    #       tell_area      ,           ,        
    >>> r1.tell_area()