python:クラスの独自の方法

13169 ワード

クラス固有のメソッド:
Pythonは、プライベート変数とメソッドをカスタマイズするほか、独自のメソッドを定義することもできます.独自のメソッドは、通常のメソッドのようにコードで直接呼び出すのではなく、特殊な場合や特殊な構文を使用する場合にpythonによって呼び出されます.形を見るとXXX__の変数や関数名に注意する必要がありますpythonでは特別な用途があります
__str__方法:
例1:
class Student:
    def __init__(self,name):
        self.name = name
		
s = Student("xiaoh")
#print(Student("xiaohong"))
print(s)                     #        

#          :<__main__.student object="" at=""/>

1、上記のコードから、1つのクラスのインスタンスを直接出力すると、特殊な文字列(プログラム開発者が使用する)が得られることがわかる2、1つのクラスのインスタンスをstrにするには、特殊な方法が必要である_str__()メソッド
3、__str__メソッドは、インスタンスオブジェクトの文字列記述としてreturn文字列タイプの戻り値を必要とします.
例2:
class Student:
    def __init__(self,name):
        self.name = name

    def __str__(self):
        return "    :%s" % self.name

s = Student("xiaoh")
#print(Student("xiaohong"))
print(s)               

#          :    :xiaoh

例3:
class Person(object):
    def __init__(self, gender):
        self.name = "BOb"           # "BOb"       name,  __init__     name  
        self.gender = gender

class Student(Person):
    def __init__(self, gender, score):
        super().__init__(gender)
        self.score = score
    def __str__(self):
        return '(Student: %s, %s, %s)' % (self.name, self.gender, self.score)
    __repr__ = __str__

s = Student('male', 88)
print(s)

#          :(Student: Bob, male, 88)

 
反復器:
1、反復の意味はループに似ており、各ループのプロセスは反復のプロセスと呼ばれ、各反復の結果は次の反復の初期値として使用される.反復メソッドを提供するコンテナは反復器と呼ばれ、通常接触する反復器にはシーケンス(リスト、メタグループ、文字列)があり、辞書(辞書反復は反復キーのみ)も反復器であり、反復操作(反復可能オブジェクトと呼ばれる)がサポートされています.
2、コンテナは複数の要素をまとめたデータ構造で、コンテナ内の要素は1つずつ反復して取得することができ、in,not inキーワードで要素がコンテナに含まれているかどうかを判断することができる.
3、反復器を返すことができるオブジェクトはすべて反復可能オブジェクトと呼ぶことができる.反復についてpythonは2つのBIF:iter()とnext()を提供します.
4、iter()関数は反復器を生成するために使用されます:1つのコンテナオブジェクトに対してiter()を呼び出すとその反復器が得られ、next()関数を呼び出すと反復器は次の値を返し、反復器に値がなければpythonを返すとStopIterationの異常が放出されます
5、iter()メソッドの構文は以下の通りです.
iter(object[, sentinel])
object --          。
sentinel --           ,   object           (   ),  ,iter          ,            __next__()   ,     object。

1、2番目のパラメータが指定されていない場合、1番目のパラメータは反復可能なプロトコル(すなわちiter()メソッドを実装した)をサポートするセット(辞書、セット、可変セット)であるか、0から始まる整数パラメータを受信するシーケンス(メタグループ、リスト、文字列)をサポートするシーケンスプロトコル(すなわちgetitem()メソッドを実装した)である必要があります.そうしないと、エラーが発生します.
2.第2のパラメータsentinelが提供する場合、第1のパラメータは呼び出し可能なオブジェクトでなければならない.作成された反復オブジェクトは、nextメソッドを呼び出すと呼び出され、戻り値とsentinel値が等しいとStopIteration異常が投げ出され、反復が終了します. 
例4:
name = "xiao"
it = iter(name)          #             

while True:
    try:
        each = next(it)  #  next()          
    except StopIteration:
        break
    print(each)


#          :x、i、a、o

例5:
class counter:

    def __init__(self, _start, _end):
        self.start = _start
        self.end = _end

    def get_next(self):
        s = self.start
        if(s < self.end):
            self.start += 1
        else:
            raise StopIteration

        return s


c = counter(1, 5)
iterator = iter(c.get_next, 6)    #             ,      for  
for i in iterator:
    print(i)

#          :1、2、3、4

 
反復器を実現する魔法の方法:_iter__、__next__
1、一つのクラスをforに使いたいなら....inループはlistやtupleのように1つの__を実現しなければならないiter__()メソッド.このメソッドは反復オブジェクトを返し、pythonのforループは反復オブジェクトの__を絶えず呼び出す.next__()メソッドは、StopIterationエラーが発生したときにループを終了するまでループの次の値を取得します.
2、一つの容器が反復器であれば、必ず実現しなければならない.iter__()メソッド、このメソッドは実際には反復器自体を返します.次に重点的に実現するのは_next__()メソッドは、反復のルールを決定するためです.
例6:
class Fib:
    def __init__(self):
        self.a = 0
        self.b = 1

    def __iter__(self):
        return self

    def __next__(self):
        self.a ,self.b = self.b,self.a + self.b
        if self.a >10:
            raise StopIteration
        return self.a
for number in Fib():
    print(number)
	
#          :1、1、2、3、5、8

例7:
class Fib:
    def __init__(self):
        self.a = 0
        self.b = 1

    def __iter__(self):
        return self

    def __next__(self):
        self.a ,self.b = self.b,self.a + self.b
        return self.a
if __name__ == "__main__":
    fib = Fib()
    for number in fib:
        if number > 10:
            break
        print(number)
		
#          :1、1、2、3、5、8

 
コンテナ内の要素を取得:_getitem__
上の例ではクラスFib()がforループに使用できることを実現したが,リストなどに似ているが,リストとして使用することはできない,例えばインデックスを使用する
例8:
if __name__ == "__main__":
    fib = Fib()
    for number in fib:
        if number > 10:
            break
        print(number)
	print(fib[2])     #    

リストのようにインデックスに従って要素を取得するには、__を実装する必要があります.getitem__()メソッド
例9:
class Fib:
    def __init__(self):
        self.a = 0
        self.b = 1

    def __iter__(self):
        return self

    def __next__(self):
        self.a ,self.b = self.b,self.a + self.b
        return self.a
		
    def __getitem__(self, item):
        a = 1
        b = 1
        for num in range(item):
            a, b = b, a + b
        return a

if __name__ == "__main__":
    fib = Fib()
    for number in fib:
        if number > 10:
            break
        print(number)
    print(fib[5])


#          :1、1、2、3、5、8、8

ダイナミックアトリビュートを追加:_getattr__
通常、クラスのプロパティまたはメソッドを呼び出すと、クラスのプロパティまたはメソッドが存在しない場合にエラーが発生します.
例9:
class Student:
    def __init__(self):
        self.name = "xiaohong"

student = Student()
print(student.name)
print(student.score)

"""
          :
xiaohong
AttributeError: 'Student' object has no attribute 'score'
"""

1、上記のコードから分かるように、既存の属性は正常に取得できますが、未定義の属性を取得するとエラーが発生します.このエラーを回避するには、クラスに対応するプロパティを追加するだけでなく、__を書くこともできます.getattr__()メソッド、動的にプロパティを返す
2、呼び出しが存在しない属性の場合、pythonは__を呼び出すgetattr__()プロパティを取得しようとすると、対応するプロパティが返されます.
3、属性が見つからない場合にのみ呼び出されます_getattr__()メソッド、既存のプロパティは__にありませんgetattr__()をクリックします.特定のプロパティ値が指定されていない場合は、デフォルトでnoneが返されます.
例10:
class Student:
    def __init__(self):
        self.name = "xiaohong"

    def __getattr__(self,attr):
        if attr == "score":
            return 95

student = Student()
print(student.name)
print(student.score)

#          :xiaohong、95

インスタンスによる呼び出し方法:_call__
1つのオブジェクトインスタンスには独自のメソッドと属性があり、インスタンスのメソッドを呼び出すときにインスタンス名を使用することができる.メソッド名.ただし、クラスは1つだけ定義する必要があります.call__()メソッドは、インスタンスを直接呼び出すことができる例11:
class Student:
    def __init__(self):
        self.name = "xiaohong"

    def __call__(self,score):
        self.score = score
        print("  :%s,  :%s" % (self.name,self.score))


student = Student()
student(95)

print(callable(Student()))
print(callable([1.2]))

"""
          :
  :xiaohong,  :95
True
False
"""

1、上記の結果から分かるように、call__()メソッドは、インスタンスを直接呼び出して結果を得ることができ、_call__()メソッドは、パラメータを定義することもできます.インスタンスを直接呼び出す1つの関数を呼び出すように、オブジェクトを関数と見なし、関数をオブジェクトと見なすことができます.
2、callable()関数により、1つのオブジェクトが「呼び出し可能」オブジェクトであるか否かを判断できる
 
拡張:
一、_repr__ 、 __str__
例2のコードを使用してインタラクティブモードで入力した場合:
>>> class Student:
    def __init__(self,name):
        self.name = name

    def __str__(self):
        return "    :%s" % self.name

>>> s = Student("xiao")
>>> s
<__main__.student object="" at=""/>

得られた例は例1の結果と同様であることがわかる.これは、Pythonが定義しているからです.str__()と_repr__()2つの方法、_str__()ユーザに表示するために使用され、_repr__()開発者に表示するために使用します. 
>>> class Student:
    def __init__(self,name):
        self.name = name

    def __str__(self):
        return "    :%s" % self.name
    
    __repr__ = __str__

>>> s = Student("xiao")
>>> s
    :xiao

 
二、クラスとオブジェクトに関するBIF
issubclass() :
issubclass()メソッドは、パラメータclassがタイプパラメータclassinfoのサブクラスであるか否かを判断するために使用される.関数の構文は次のとおりです.
issubclass(class, classinfo)

class --  。

classinfo --  。

   :   class   classinfo       True,     False。

例1:
class A:
    pass

class B(A):
    pass
print(issubclass(B, A)) 

#          :True

 
hasattr():
hasattr()関数は、オブジェクトに対応する属性が含まれているかどうかを判断するために使用されます.関数の構文は次のとおりです.
hasattr(object, name)
object --   。

name --          。

   :           True,     False。

例2:
class Coordinate:
    x = 10
    y = -5
    z = 0

point1 = Coordinate()
print(hasattr(point1, 'x'))   #         
print(hasattr(point1, 'no'))

#          :True、False

getattr():
getattr()関数は、オブジェクトが指定した属性値を返すために使用されます.指定した属性が存在しない場合はdefaultの値を返し、defaultパラメータが設定されていない場合はAttributeError例外を放出します.関数の構文は次のとおりです.
getattr(object, name[, default])

object --   

name --    ,    。

default --      ,        ,        ,    AttributeError。

   :       。

例3:
class A(object):
    bar = 1

a = A()
if getattr(a,"bar","       ") == 1:
    print("bar    %s" % 1)

attr_no = getattr(a,"b","       ")
print("no    %s" %(attr_no))

"""
          :
bar    1
no           
"""

setattr():
setattr()関数は、指定した属性の値を設定する関数getatt()に対応し、指定した属性が存在しない場合は新しい属性を作成し、値を割り当てます.関数の構文は次のとおりです.
setattr(object, name, value)

object --   。

name --    ,    。

value --    。

   : 

例4:
class A(object):
    bar = 1

a = A()
setattr(a,"b","        ")
setattr(a,"bar","2")

attr_no = getattr(a,"b","      ")
attr_bar = getattr(a,"bar","      ")

print("no     %s" %(attr_no))
print("bar     %s" %(attr_bar))

"""
          :
no             
bar     2
"""

delattr():
delattr()関数は属性を削除するために使用され、属性が存在しない場合はAttributeError異常が放出されます.関数の構文は次のとおりです.
delattr(object, name)
object --   。
name --         。
   : 
delattr(x, 'foobar')     del x.foobar。

例5:
class A(object):
    bar = 1
    bar_1 = "2"

a = A()
delattr(A,"bar")  #   
delattr(a,"b")

print(a.bar)    #          
print(a.bar_1)  #         

"""
          :
#AttributeError: b
#'A' object has no attribute 'bar'
"""

property( ):
property()関数の役割は、新しいクラスで属性値を返すことです.以下はproperty()メソッドの構文です.
class property([fget[, fset[, fdel[, doc]]]])

fget --         
fset --         
fdel --        
doc --       
   :       。

例6:
class Student(object):
    def __init__(self, name, score):
        self.name = name
        self.score = score

上のコードでは、Studentのscroeプロパティを変更したい場合は、次のように書くことができます.
s = Student('Bob', 59)
s.score = 60

しかし、このように書くこともできます.
s.score = 1000

したがって、score変数をプライベート変数に変更し、get_を介してattrとset_attrメソッドは、入力したパラメータが有効かどうかをチェックします(この2つのメソッドは、「クラスのアクセス権の記事で説明されています.プライベート変数ではない変数でも使用できます.」
class Student:
    def __init__(self,name,score):
        self.name = name
        self.__score = score

    def get_score(self):
        return self.__score

    def set_score(self,value):
        if value < 0 or value >100:
            raise ValueError('invalid score')
        else:
            self.__score = value

student = Student("Bob",88)
student.set_score (10)
print(student.get_score())

1、そうすると、s.set_score(1000)はエラーを報告します.このget,setメソッドを用いて1つの属性へのアクセスをカプセル化することは,多くのオブジェクト向けプログラミング言語でよく見られる.
2、でもs.get_と書くscore()とs.set_score()はs.scoreを直接書いていません.
3.また、この部分のコードがこのように修正すると、後のコードは修正する必要がある:前のアクセス属性が変更されていない場合はインスタンス名である.属性名は、コード変更後に属性にアクセスする場合はインスタンス名に変更する.get_score()(クラス外アクセスプライベート変数、メソッドによるプライベート変数へのアクセス).インスタンス名など、すべての付与文も変更する必要があります.属性名=valueをインスタンス名に変更する.set_score(value).明らかにこのような修正は面倒で間違いやすい.これがpropertyのキラキラ登場が必要な場所です
class Student:
    def __init__(self,name,score):
        self.name = name
        self.__score = score

    def get_score(self):
        return self.__score

    def set_score(self,value):
        if value < 0 or value >100:
            raise ValueError('invalid score')
        else:
            self.__score = value

    student_score = property(get_score, set_score)

student = Student("Bob",88)

student.student_score = 66

print(student.get_score())
print(student.student_score)   #      student_score     

#          :66、66

1、簡単に言えば、propertyはメンバー属性(student_score)のアクセスエントリにいくつかのコード(get_scoreおよびset_score)を付加する.任意の取得student_score値のコードはget_を自動的に呼び出す辞書表ではなくscore(_dict_)を使用してインポートしたストロークVSラム速度のデータ点を示します.同じようにstudent_に割り当てられていますscore値のコードもset_を自動的に呼び出しますscore().これはPythonのクールな機能です.
2、propertyを使用することで、お客様のコードを変更する必要がなく、クラスを変更し、値制約を実現しました.そのため、私たちの実装は後方互換性があります.最後に、実際のスコアはプライベート変数に格納されていることに注意してください.scoreの.属性student_scoreはpropertyオブジェクトであり、このプライベート変数にインタフェースを提供するために使用されます.