Python-クラスへのアクセス

4771 ワード

Classの内部には、属性とメソッドがあり、外部コードはインスタンス変数を直接呼び出す方法でデータを操作することができ、内部の複雑な論理を隠すことができます.
ただし、外部コードは、1つのインスタンスのnamescore属性を自由に変更することができます.
>>> class Student(object):
...     def __init__(self,name,score):
...             self.name = name
...             self.score = score
...
>>>
>>> bart = Student('zth',80)
>>>
>>> bart.score
80
>>> bart.score = 90
>>>
>>> bart.score
90

 
クラスで定義された非構築メソッドは、クラス内の構築メソッドインスタンス変数のプロパティを呼び出すことができます.
内部属性が外部からアクセスされないようにするには、属性の名前に下線を2つ付けることができます__Pythonでは、インスタンスの変数名が__で始まると、プライベート変数(private)になり、内部のみアクセスでき、外部はアクセスできないので、Studentクラスを変更します.
>>> class Student(object):
...     def __init__(self,name,score):
...             self.__name = name
...             self.__score = score
...     def print_score(self):
...             print('%s: %s'%(self.name,self.score))
...
>>>
>>> bart = Student('zth',90)
>>>
>>> bart.__scroe
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: 'Student' object has no attribute '__scroe'

 
これにより、外部コードがオブジェクトの内部の状態を勝手に変更できないことが確保され、アクセス制限の保護によってコードがより丈夫になります.
Studentクラスに追加できるget_name およびget_score 外部コードからnameとscoreを取得する方法
Studentクラスに追加できるset_score メソッド外部コード修正score
Pythonでは、プライベート変数と対応するsetメソッドを定義することで、無効なパラメータの入力を避けるためにパラメータチェックを行うのに役立ちます.
 
class Student(object):
    def __init__(self, name, score):
        self.__name = name
        self.__score = score

    def get_name(self):
        return self.__name
    
    def get_score(self):
        return self.__score
    
    def set_score(self,score):
        
        if 0<= score <=100:
            self.__score = score
        else:
            raise ValueError('Error score')
        
        
zth = Student('zth',80.5)

print("  :%s"%zth.get_name())
print("     :%s"%zth.get_score())


zth.set_score(90)

print("     :%s"%zth.get_score())

# zth.set_score(123)

実行結果:
  :zth
     :80.5
     :90

 
なお、Pythonでは、変数名が__xxx__に類似している、つまり二重下線で始まる、しかも二重下線で終わる、特殊変数であり、特殊変数は直接アクセス可能であり、private変数ではないので、__name____score__・・のような変数名は使用できない.
場合によっては、下線で始まるインスタンス変数名、例えば_nameを見ることができます.このようなインスタンス変数は外部からアクセスできますが、約束の俗成の規定に従って、このような変数を見ると、「私は質問されてもいいですが、私をプライベート変数と見なして、勝手にアクセスしないでください」という意味です.
二重下線の先頭のインスタンス変数は、必ず外部からアクセスできないのではないでしょうか.実はそうではありません.直接アクセスできない__namePythonインタプリタが対外的に__name変数を_Student__nameに変更したため、依然として_Student__nameでアクセス可能__name変数
>>> zth.__score
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: 'Student' object has no attribute '__score'
>>> zth._Student__name
'zth'

しかし、異なるバージョンのPython解釈器が__nameを異なる変数名に変更する可能性があるため、そうしないことを強くお勧めします.
総じて言えば、Python自体はあなたが悪いことをするのを止めるメカニズムがなく、すべては自覚にかかっています.
最後に、次のような誤った書き方に注意します.
>>> class Student(object):
...     def __init__(self,name,score):
...             self.__name = name
...             self.__score = score
...     def get_name(self):
...             return self.__name
...
>>>
>>> zth= Student('zth',80)
>>> zth.get_name()
'zth'
>>>
>>> zth.__name = 'fbb'
>>>
>>> zth.get_name()
'zth'

表面的には外部コードが「成功」に設定されている__name変数ですが、実はこの__name変数とclass内部の__name変数は1つの変数ではありません!内部の__name変数はPythonインタプリタによって自動的に変更された_Student__name外部コードはbart新たに__name変数が追加された.
 
クラスにもプライベートな方法があります.
>>> class PrivateMethod(object):
...     def __foo(self):                #     
...             print("       ")
...     def foo(self):                  #     
...             print("       ")
...             print("           ")
...             self.__foo()
...             print("        ")
...
>>>
>>> zth = PrivateMethod()
>>>
>>> zth.foo()
       
           
       
        
>>>
>>> zth.__foo()
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: 'PrivateMethod' object has no attribute '__foo'