面接官と談笑する|Python対象へのアクセス制御
6464 ワード
Pythonは設計当初からオブジェクト向けの言語であり,オブジェクト向け思想の最初の要素はパッケージである.パッケージとは、通俗的にはクラスの属性と方法であり、公有と私有に分けられ、公有は外部にアクセスされ、私有は外部にアクセスされない.これがパッケージの中で最も重要な概念であるアクセス制御である.
アクセス制御には、プライベート、保護、パブリックの3つのレベルがあります.
プライベート(Private):クラス自体のみが保護(Protected):クラス自体とサブクラスのみがパブリック(Public):任意のクラスにアクセスできます.
PythonはJavaとは異なり、アクセス制御子(private/public/protected)があるため、Pythonのアクセス制御も応募者に無視され、間違えられやすい.
パブリック(Public)
Pythonのクラスでは、デフォルトで定義されている属性はすべて共通です.
上記のクラス
保護(Protected)
Pythonで保護された属性を定義し、その名前の前に下線
クラス
次に、クラスの外部で属性にアクセスできるかどうかを逆方向に検証してみます.上のコードの出力部分を次のように変更します.
驚いたことに、間違いを報告せずに正しい値を出力した.
Pythonでは、保護された変数を下線で定義するのは、言語レベルではなく、約束された規範であり、本当にアクセス制御が実現されているので、私たちが定義した保護変数は、依然として外部にアクセスすることができます(これはfeatureであり、bugではありません).
プライベート(private)
Pythonはプライベート属性を定義し、属性名に下線
深く入ると--プライベート属性は本当にアクセスできませんか?
プライベート属性が本当にアクセスできないかどうかを知るには、Pythonがプライベート属性をどのように実現するかから始める必要があります.CPythonでは、二重下線の属性を
実行すると、
特例
二重下線を使用してプライベート属性を定義する場合、属性の後にも二重下線がある場合、この属性はPython解釈器によってマジックメソッドとして扱われ、プライベート処理は行われません.
上のコードは123を出力し、Python解釈器が
もう一つの特例
定義された属性名を
関数のアクセス制御
先に主に属性のアクセス制御を紹介したが,Pythonでは関数は一等公民であり,一等公民とは関数が変数のように使用できるため,関数のアクセス制御と属性のように上の規則を適用する.
Pythonのプライベートメニューに注目
アクセス制御には、プライベート、保護、パブリックの3つのレベルがあります.
プライベート(Private):クラス自体のみが保護(Protected):クラス自体とサブクラスのみがパブリック(Public):任意のクラスにアクセスできます.
PythonはJavaとは異なり、アクセス制御子(private/public/protected)があるため、Pythonのアクセス制御も応募者に無視され、間違えられやすい.
パブリック(Public)
Pythonのクラスでは、デフォルトで定義されている属性はすべて共通です.
class Foo(object):
bar = 123
def __init__(self, bob):
self.bob = bob
print(Foo.bar) # 123
foo = Foo(456)
print(foo.bob) # 456
上記のクラス
Foo
のbar
属性はクラス属性であり、__init__
メソッドで定義されたbobはインスタンス属性であり、bar
およびbob
はいずれも共通の属性であり、外部からアクセス可能であり、それぞれprintクラスのbar
およびインスタンスのbob
は対応する値を出力する.保護(Protected)
Pythonで保護された属性を定義し、その名前の前に下線
_
を付けるだけで、Fooメソッドのbob
とbar
を_bob
と_bar
に変更します.彼らは保護された属性になります.コードは以下の通りです.class Foo(object):
_bar = 123
def __init__(self, bob):
self._bob = bob
class Son(Foo):
def print_bob(self):
print(self._bob)
@classmethod
def print_bar(cls):
print(cls._bar)
Son.print_bar() # 123
son = Son(456)
son.print_bob() # 456
クラス
Son
を定義すると、Foo
から継承され、保護されたオブジェクトはクラスの内部およびサブクラスにのみアクセスでき、print(Son._bar)
またはprint(son._bob)
を直接呼び出してこの2つの属性の値を出力することはできないため、print_bar
およびprint_bob
メソッドを定義し、サブクラスでの出力を実現し、このコードも正常に_bar
および_bob
の値を出力した.次に、クラスの外部で属性にアクセスできるかどうかを逆方向に検証してみます.上のコードの出力部分を次のように変更します.
print(Son._bar) # 123
son = Son(456)
print(son._bob) # 456
驚いたことに、間違いを報告せずに正しい値を出力した.
Pythonでは、保護された変数を下線で定義するのは、言語レベルではなく、約束された規範であり、本当にアクセス制御が実現されているので、私たちが定義した保護変数は、依然として外部にアクセスすることができます(これはfeatureであり、bugではありません).
プライベート(private)
Pythonはプライベート属性を定義し、属性名に下線
__
を2つ付ける必要があります.上のコードを修正して、実行すると次のコードのいずれかのprintが間違っていることがわかります.class Foo(object):
__bar = 123
def __init__(self, bob):
self.__bob = bob
class Son(Foo):
def print_bob(self):
print(self.__bob) # Error
@classmethod
def print_bar(cls):
print(cls.__bar) # Error
print(Son.__bar) # Error
son = Son(456)
print(son._bob) # Error
深く入ると--プライベート属性は本当にアクセスできませんか?
プライベート属性が本当にアクセスできないかどうかを知るには、Pythonがプライベート属性をどのように実現するかから始める必要があります.CPythonでは、二重下線の属性を
_ClassName__PropertyName
の形式に変更し、コードで実証します.class Foo(object):
__bar = 123
print(Foo._Foo__bar) # 123
実行すると、
__bar
の値が正常に出力されていることがわかりますが、Python解釈器によってプライベート属性の処理が異なるため、プライベート属性へのアクセスは推奨されません.特例
二重下線を使用してプライベート属性を定義する場合、属性の後にも二重下線がある場合、この属性はPython解釈器によってマジックメソッドとして扱われ、プライベート処理は行われません.
class Foo(object):
__bar__ = 123
print(Foo.__bar__) # 123
上のコードは123を出力し、Python解釈器が
__bar__
をプライベート属性としていないことを証明した.プライベート属性を定義する場合は、名前の最後に下線が1つしかないことに注意してください.もう一つの特例
定義された属性名を
__
と呼ぶとしたら?直接試してみてください.class Foo(object):
__ = 123
print(Foo.__) # 123
__
という名前の属性もプライベート属性とはみなされず、名前が複数の下線の属性もプライベート属性ではないことがわかります(_______
).関数のアクセス制御
先に主に属性のアクセス制御を紹介したが,Pythonでは関数は一等公民であり,一等公民とは関数が変数のように使用できるため,関数のアクセス制御と属性のように上の規則を適用する.
Pythonのプライベートメニューに注目