章VIIのオブジェクト指向(8):パッケージ

7.11パッケージ

パッケージに隠された単純な意味ではありません

まず、どのように隠されたパッケージを達成するために

隠し属性(属性データ、関数属性)

__という名前のプロパティで始まるPythonのクラスは、非表示になります。

注意:__ __パイソンの終わりの始まりは、組み込み関数の意味で、隠されません。

実際には、隠し属性は、ときに、クラス定義の変形が発生し、変形操作の名前です。

  • プロパティの隠された機能:
    1. クラス外でコールするときに、プロパティ名で定義することはできません。obj__AttrName
    2. クラス内に直接名はときに呼び出すように定義されている属性のことができます。obj__AttrName

      隠し属性のクラス定義が変更されたとき、それは直接的に変形し、コールの属性名をすることができますので、

    3. サブクラスは、親クラスの先頭にプロパティをオーバーライドすることはできません__

class A:
    __x = 1  # 实际上隐藏是在定义类的时候变形了属性名,变成了 _A__x
    
    def __init__(self, name):
        self.__name = name  # 变形成 _A__name
        
    def __foo(self):  # 变形成 _A__foo
        print('run foo')
    
    def bar(self):
        self.__foo()  # 类调用的时候也被变形成 _A__foo了,所以跟上面变化后相同,所以在类内部可以调用
        print('from bar')

# print(A.__x)  # 会报错
# print(A.__foo)  # 会报错

a = A('a')
# print(a.__name)  # 会报错
print(a._A__name)  # 隐藏属性的特点1,不过不推荐这么访问

# 我们看看他们的名称空间发生了什么
print(A.__dict__)
print(a.__dict__)

a.bar()  # 隐藏属性的特点2

結果:

a
{'__module__': '__main__', '_A__x': 1, '__init__': <function A.__init__ at 0x0000000001E5A6A8>, 
'_A__foo': <function A.__foo at 0x0000000001E5A7B8>, '__dict__': <attribute '__dict__' of 'A' objects>, 
'__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None}
{'_A__name': 'a'}
run foo
from bar

私たちは、クラスの定義では、隠し属性が変形していたことがわかります。

隠し属性3時コード例の特徴:

class Foo:
    def __func(self):  # _Foo__func
        print('from foo')
        
class Bar(Foo):
    def __func(self):  # _Bar__func
        print('from bar')

b = Bar()
print(Bar.__dict__)

注意が必要な問題のこの変形要約:

  1. この異常は、実際には、変形の感覚の中に隠されていません。
  2. この変形は、場合にのみ、クラス定義を発生し、1回だけ発生します。クラス定義の後、すべての歪んです。

    クラスの増加の定義の開始後__属性定義された属性が変形されていませんが、以前にクラスに追加しました。
    ``
    クラスB:
    __X 1 =。

     def __init__(self, name):
         self.__name = name

    B = B( 'B')
    プリント(B .__ dict__にマジック)
    B = Y 2 .__
    プリント(B. 辞書)#1 __y名前空間がクラスに追加されるように

    年齢= .__ 11 B
    プリント(B. 辞書)#1 __age名前空間がクラスに追加されるように、
    执行结果:
    { '_B__name': 'B'}
    { ' Module1のが ':' '、 '_B__x' :. 1 ' INIT ' :<関数B .__ 0x000000000288A6A8 AT init__> ' 辞書 ':<属性' dictの 'B'のオブジェクトの'> ' weakref ':<属性' weakref 'B'のオブジェクトの'> ' DOC ':なし、「__y ':2}
    {' _B__name ':' B '' __age「:11}
    `` `
  3. 続いて、あなたはサブクラスは、独自のメソッドをカバーしたくない場合は、親クラスは、メソッドを隠しのように定義することができます
    `` `
    クラスA:
    DEF __foo(セルフ):
    印刷(「A.foo」)

     def bar(self):
         print('A.bar')
         self.__foo()

    クラスB(A):
    DEF __foo(自己):
    プリント( 'B.foo')

    B = B()
    b.bar()#fooが属性を隠されていない場合は、FOOにあるバーの父親がクラスBを呼び出しますが、隠し属性を使用すると、クラスA __foo呼ばれると呼ばれる
    执行结果:
    A.barの
    A. FOO
    `` `

意義パッケージ

1.意義カプセル化されたデータは、属性:内部と外部との間に明確な区別、外部制御隠し属性の操作。

あなたは、直接クラス属性外のパッケージにアクセスすることはできませんが、それでもクラス内で直接アクセスすることができます。
外部から間接的にしかアクセス属性パッケージ。私たちは、メソッドのインタフェース機能を定義することによって、アクセスを制御することができます。
外で直接、唯一のインタフェースを介して変更され、クラス属性を変更することはできません

例:

class People:
    def __init__(self, name, age):
        self.__name = name  # 封装数据属性
        self.__age = age
    
    def tell_info(self):  # 设置接口让用户只能以提供的接口访问数据
        print('Name:%s ; Age:%s' % (self.__name, self.__age))
    
    def set_info(self, name, age):  # 设置接口函数来限制用户修改的方式
        if not isinstance(name, str):  # 设置条件
            print('名字必须是字符串')
            return 
        if not isinstance(age, int):  # 设置条件
            print('年龄必须是int类型')
            return
        self.__name = name
        self.__age = age
        
p = People('a',11)

p.tell_info()
p.set_info('b', '12')
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()

パッケージ化とスケーラビリティ

私たちは何のheight属性を開始しない、クラスの部屋を持っており、後で追加しました。ユーザー・インタフェース・メソッドが呼び出されているので、そうどんなに私たちの内部の修正、ユーザーは同じように呼び出されていません。これは、拡張性を反映しています

class Room:
    def __init__(self, name, owner, weight, lenth, height):  # 后增加了height
        self.name = name
        self.owner = owner
        
        self.__weight = weight
        self.__lenth = lenth
        self.__height = height  # 追加height属性
        
        
    def tell_result(self):  # 
        return self.__weight * self.__lenth * self.__height  # 追加了height

r = Room('卫生间','a', 10, 10, 10)  # 追加属性

# 用户调用接口是完全没有变化的
r.tell_result()

おすすめ

転載: www.cnblogs.com/py-xiaoqiang/p/11210450.html