滑らかなパイソン、流暢Pythonの第十章ノート

変更、ハッシュとスライスしたシーケンス。

いくつかの利用__getattr__と__getitem__ようにいくつかの話本は、私は再びそれを学習強化するために、早期のノートのいくつかを、持っています。

 

配列のインポート配列から
輸入数学
輸入reprlib


クラスベクトル:
    タイプコード= 'D'

    デフ__init __(自己、コンポーネント):
        self._components =配列(self.typecode、部品)

    デフ__iter __(自己):#は__next__イテレータオブジェクトは、プロパティを持って返します。
        「」「」「だけでなく、__iter__特性を有する多変量値、ループにも使用することができます」
        ITERを返す(self._components)

    デフ__repr __(自己):
        コンポーネント= reprlib.repr(self._components)番号#すぎるの代わりに使用することができます...
        #プリント(部品)
        コンポーネント=コンポーネント[components.find( '['):-1]
        リターンF '{自己.__クラス__.__名__}({成分})'

    デフ__str __(自己):
        リターンSTR(タプル(自己))

    デフ__bytes __(自己):
        リターン(バイト([ORD(self.typecode)])+
                バイト(self._components))

    デフ__eq __(自己、他):
        リターンタプル(自己)==タプル(その他)

    デフ__(自己)__abs:#は、長い直角三角形の斜辺をリターンをABS
        リターンmath.sqrt(自己中xの合計(X * X))

    デフ__bool __(自己):#は直接オブジェクトの値を呼び出し、その後、bool値を使用し、ABS
        リターンブール値(ABS(自己))

    @classmethod
    デフfrombytes(CLS、オクテット):
        最初の読み出しタイプコードのタイプコード= CHR(オクテット[0])#アレイ
        menv = memoryview(オクテット[1:])キャスト(型コード)。
        印刷(menv)
        リターンCLS(menv)



V =ベクトル([1、2])

 

そして、[456]で                                                                                        
OUT [456]:配列( 'D'、[1.0、2.0])
ベクター([1.0、2.0])

V =ベクトル(範囲(100)):[457]に                                                                   

そして、[458]で                                                                                        
OUT [458]:配列( 'D'、[0.0、1.0、2.0、3.0、4.0、...])
ベクター([0.0、1.0、2.0、3.0、4.0、...])

そして、[459]:P(V)                                                                                   
OUT [459]:「(0.0、1.0、2.0、3.0、4.0、5.0、6.0、7.0、8.0、9.0、10.0、11.0、12.0、13.0、14.0、15.0、16.0、17.0、18.0、19.0、20.0、21.0 、22.0、23.0、24.0、25.0、26.0、27.0、28.0、29.0、30.0、31.0、32.0、33.0、34.0、35.0、36.0、37.0、38.0、39.0、40.0、41.0、42.0、43.0、44.0、45.0、46.0 、47.0、48.0、49.0、50.0、51.0、52.0、53.0、54.0、55.0、56.0、57.0、58.0、59.0、60.0、61.0、62.0、63.0、64.0、65.0、66.0、67.0、68.0、69.0、70.0、71.0 、72.0、73.0、74.0、75.0、76.0、77.0、78.0、79.0、80.0、81.0、82.0、83.0、84.0、85.0、86.0、87.0、88.0、89.0、90.0、91.0、92.0、93.0、94.0、95.0、96.0 、97.0、98.0、99.0「)

 

v.frombytes(バイト(V)):[468]に                                                                    
<0x108578940のメモリ>
OUT [468]:配列( 'D'、[0.0、1.0、2.0、3.0、4.0、...])
ベクター([0.0、1.0、2.0、3.0、4.0、...])

[469]で:    

 

10.3およびアヒルプロトコルタイプ

 

Pythonは単にプロトコルシーケンスの実装に合わせて、継承を使用せずに完全な配列タイプで作成されました。

オブジェクト指向プログラミングでは、契約は非公式インターフェースは文書のみで定義されている、それがコードで定義されていません。

カラムとして、Pythonは配列プロトコルを__len__と__getitem__の2つだけの方法を必要とします。

任意のクラスは、限り、これらのメソッドの両方を達成するための標準的なシグネチャとセマンティクスの使用などの任意の場所にシーケンスを期待することができます。

 

10.4VectorクラスSecond Editionの:利用可能な配列スライス、スライス原則。

    デフ__getitem __(自己、インデックス):
        リターンself._components [インデックス]

    デフ__len __(自己):
        リターンでlen(self._components)

 シーケンス・プロトコルを達成するために2つのメソッドを追加します。

V =ベクトル(範囲(10)):[470]に                                                                      

そして、[471]で                                                                                        
OUT [471]:ベクター([0.0、1.0、2.0、3.0、4.0、...])

そして、[472]〜[3:5]                                                                                   
OUT [472]:配列( 'D'、[3.0、4.0])

そして、[473]:lenは(V)                                                                                   
アウト[473]:10

 

スイッチングの原理を理解しましょう。

S = MySeq():[475]に                                                                               

S [1]:[476]に                                                                                     
アウト[476]:1

S [1:2] [477]で                                                                                   
OUT [477]:スライス(1、2、なし)

S [1:5:2] [478]で                                                                                 
OUT [478]:スライス(1、5、2)

S [1:2:2] [479]で                                                                                 
OUT [479]:スライス(1、2、2)

S [1:1:2] [480]で                                                                                 
OUT [480]:スライス(1、1、2)

S [1:2,3] [481]で                                                                                 
OUT [481]:(スライス(1、2、なし)、3)

S [1:2,3:8] [482]で                                                                               
OUT [482]:(スライス(1、2、なし)、スライス(3,8、なし))

[483]で:   

 また、場合単一数、それらはスライスのさらなる例に戻され、その後数。

[483]で:DIR(スライス)                                                                               
アウト[483]: 
['__クラス__'、
 「__delattr__」
 「__ DIR__」
 「__doc__」
 「__eq__」
 '__フォーマット__'、
 '__Ge__'
 「__getattribute__」
 「__gt__」
 '__ハッシュ__'、
 '__初期化__'、
 「__init_subclass__」
 '__Le__'
 「__lt__」
 '__Ne__'
 '__新着__'、
 「__reduce__」
 「__reduce_ex__」
 「__repr__」
 「__setattr__」
 '__のサイズ__'、
 「__str__」
 「__subclasshook__」
 「インデックス」、
 '開始'、
 「ステップ」、
 'やめる']

 スライス「インデックス」は、本当に私たちが優雅にインデックスと負のインデックスを扱う助け、それが目標を超える長さの縮図となっています

[484]で:スライス(なし、10、2).indices(3)                                                            
OUT [484]:(0、3、2)

[485]で:スライス(-3、なし).indices(10)                                                               
OUT [485]:(7、10、1)

 

スライス(-3、なし).indices(5):[486]に                                                                
OUT [486](2、5、1)

 

'ABCDE':[1]における[10:2]                                                                    
アウト[1]: 'エース'

[2]で: 'ABCDE' [ -  3:]                                                                      
アウト[2]: 'CDE'

[3]において: 'ABCDE' [2:5:1]                                                                    
アウト[3]: 'CDE'

 だから、スライスされたときに我々は多くのパラメータを使用して、書いていない引数がインデックスに(オブジェクト)lenの長さである必要があり、デフォルトの作業、に依存しています。

 

10.4.2 __getitem__メソッドは、セクションを処理することができます。

あまりにも低をスライスして返される配列の前に、今のオブジェクトを介してスライスに戻り、又は単一のデジタル値を返します。

    デフ__getitem __(自己、インデックス):
        CLS =タイプ(自己)
        でisinstance(インデックス、スライス)の場合:
            戻りCLS(self._components [インデックス])
        elifのでisinstance(インデックス、numbers.Integral):
            リターンself._components [インデックス]
        そうしないと:
            MSG = '{CLS .__ name__}指数は整数でなければなりません'
            レイズはTypeError(msg.format(CLS = CLS))
V =ベクトル(範囲(10)):[496]に                                                                    

そして、[497]に[1:3]                                                                                   
OUT [497]:ベクター([1.0、2.0])

そして[498]〜[4]                                                                                     
アウト[498]:4.0

そして、[499]に[4.5]                                                                                   
-------------------------------------------------- -------------------------
TypeError例外トレースバック(最新の呼び出しの最後)
<ipython-入力499-0f2464134463>で<モジュール>
----> 1 V [4,5]

<ipython-入力495-3d153cb2c4de>で__getitem __(自己、インデックス)
     それ以外の45:
     46 MSG = '{CLS .__ name__}指数は整数でなければなりません'
---> 47昇給の例外TypeError(msg.format(CLS = CLS))
     48 
     49デフ__len __(自己):

TypeError例外:ベクトルインデックスは整数でなければなりません

 

クラス10.5Vector第3版:ダイナミックアクセス属性

ここで、いとこによって、[0]のV VXを取得したいV [1]等を取得VY

強力ないとこ、

Pythonのは、取得したプロパティをオブジェクト

それが財産を所有しているかどうかをまず__getattriburte__検索、

そのような属性が存在しないオブジェクトのクラスを見つけられませんでした、

ない場合は、継承ツリーで検索を続けます、

くそー、まだ私はそれが内部に来るように__getattr__見つけることができません。

 

    定義されてもよいSHORTCUT_NAME =「xyzt」#1 __getattr__は、修飾の外部を定義することができます。
    デフ__getattr __(自己、インデックス):
        lenの場合(インデックス)== 1:
            POS = self.shortcut_name.find(インデックス)
            もし0 <= POS <LEN(self._components):
                リターンself._components [POS]
            MSG = '{.__名前__!R}オブジェクトには、属性{!R}を持っていません'
            引き上げはAttributeError(msg.format(自己.__ class__、インデックス))

 少し少し異なるとコードブックは、ビットは、力にロードされた例はSHORTCUT_NAMEを変更することができます

V =ベクトル(レンジ(3)):[517]に                                                                     

そして、[518]:X                                                                                      
OUT [518]:0.0

VY:[519]で                                                                                      
アウト[519]:1.0

そして、[520]:トン                                                                                      
-------------------------------------------------- -------------------------
AttributeErrorにトレースバック(最新の呼び出しの最後)
<ipython入力-520-ebe607c98c18>で<モジュール>
----> 1つのVT

<ipython-入力508-4a33821354a0>で__getattr __(自己、インデックス)
     54リターンself._components [POS]
     55 MSG = '{.__名前__!R}オブジェクトには、属性{!R}を持っていません'
---> 56レイズはAttributeError(msg.format(自己.__ class__、インデックス))
     57 
     58デフ__len __(自己):

AttributeError:「ベクトル」オブジェクトが無属性「T」を持っています

[521]で:v.shortcut_name = 'ABC'                                                                    

そして[522] VB                                                                                      
アウト[522]:1.0

 のは面白いましょう。

[521]で:v.shortcut_name = 'ABC'                                                                    

そして[522] VB                                                                                      
アウト[522]:1.0

そして、[523] VA                                                                                      
アウト[523]:0.0

そして[524] VA = 10                                                                                 

そして、[525] VA                                                                                      
アウト[525]:10

そして、[526]で                                                                                        
OUT [526]:ベクター([0.0、1.0、2.0])

 これでは、値VAを変更しますが、何の変化の例は確かにありません。

私はVA Vそれに属性を追加する場合は、比較的単純なことを高く評価し、後続の読取りオブジェクトはメソッド___getattr__ VAを取得されていません。

 

オブジェクトは読み取り専用ですので、私は、オブジェクトの値を変更したいと考えていましたしない理由行動__setattr__を制限するので、単一の文字によって財産を大切にのみ制限することができます。避ける誤解

__getattr__メソッドを実現した場合、我々は、オブジェクトの一貫性のない動作を防ぐために__setattr__方法を定義する必要があり、そこにあります。

配列のインポート配列から
輸入数学
輸入reprlib
インポート番号


クラスベクトル:
    タイプコード= 'D'

    デフ__init __(自己、コンポーネント):
        self._components =配列(self.typecode、部品)

    デフ__iter __(自己):#は__next__イテレータオブジェクトは、プロパティを持って返します。
        「」「」「だけでなく、__iter__特性を有する多変量値、ループにも使用することができます」
        ITERを返す(self._components)

    デフ__repr __(自己):
        コンポーネント= reprlib.repr(self._components)番号#すぎるの代わりに使用することができます...
        #プリント(部品)
        コンポーネント=コンポーネント[components.find( '['):-1]
        リターンF '{自己.__クラス__.__名__}({成分})'

    デフ__str __(自己):
        リターンSTR(タプル(自己))

    デフ__bytes __(自己):
        リターン(バイト([ORD(self.typecode)])+
                バイト(self._components))

    デフ__eq __(自己、他):
        リターンタプル(自己)==タプル(その他)

    デフ__(自己)__abs:#は、長い直角三角形の斜辺をリターンをABS
        リターンmath.sqrt(自己中xの合計(X * X))

    デフ__bool __(自己):#は直接オブジェクトの値を呼び出し、その後、bool値を使用し、ABS
        リターンブール値(ABS(自己))

    デフ__getitem __(自己、インデックス):
        CLS =タイプ(自己)
        でisinstance(インデックス、スライス)の場合:
            戻りCLS(self._components [インデックス])
        elifのでisinstance(インデックス、numbers.Integral):
            リターンself._components [インデックス]
        そうしないと:
            MSG = '{CLS .__ name__}指数は整数でなければなりません'
            レイズはTypeError(msg.format(CLS = CLS))

    定義されてもよいSHORTCUT_NAME =「xyzt」#1 __getattr__は、修飾の外部を定義することができます。
    デフ__getattr __(自己、インデックス):
        lenの場合(インデックス)== 1:
            POS = self.shortcut_name.find(インデックス)
            もし0 <= POS <LEN(self._components):
                リターンself._components [POS]
            MSG = '{.__名前__!R}オブジェクトには、属性{!R}を持っていません'
            引き上げはAttributeError(msg.format(自己.__ class__、インデックス))
        
    デフ__setattr __(自己、キー、値):
        CLS =タイプ(自己)#除去クラス
        lenの場合(キー)== 1:#は、文字列を設定することができますされていないプロパティ
            cls.shortcut_nameでのキー場合:#は、リストの内部に定義されました
                エラー= 'readonly属性{ATTR_NAME!R}'
            elifのkey.islower():#小文字の文字はありません
                エラー=「{cls_name!R}でできない属性セット 『』に 『Z』」
            他:文字の大文字位別の可能性であります
                エラー=「」
            エラーの場合:
                MSG = error.format(cls_name = CLS、ATTR_NAME =キー)
                レイズはAttributeError(MSG)
        スーパー(ベクター、自己).__ SETATTR __(キー、値)

    デフ__len __(自己):
        リターンでlen(self._components)
    @classmethod
    デフfrombytes(CLS、オクテット):
        最初の読み出しタイプコードのタイプコード= CHR(オクテット[0])#アレイ
        menv = memoryview(オクテット[1:])キャスト(型コード)。
        印刷(menv)
        リターンCLS(menv)



V =ベクトル([1、2])

 このテストでは、テストされ、上にない、それが実行することができます。

 

10.6 Ventorバージョン4:ハッシュ良い速い等価テスト

 

場合ハッシュ値取得により、第1の2次元、二つの値のXOR

ハッシュ(self._x)^ハッシュ(self._y)

内部ハッシュの各要素がなければならない多次元配列の後に、XOR次々。

使用を減らすために。

 

renduce(FUNC、リスト)

RES = FUNC(リスト[0]、リスト[1])であります

その後、RES = FUNC(RES、リスト[2])

そして、それはそう、上に行く終え要素を知るため、最終戻り値に復帰されています。

[535]で:functoolsから減らすインポート                                                             

[536]で:(^ B、範囲(10)ラムダA、B)を低減                                                         
アウト[536]:1

オペレータインポートXOR:[537]に                                                                 

(XOR、範囲(10))を減少させる:[538]に                                                                    
アウト[538]:1

 オペレータモジュールは、それによって、ラムダ式の使用を低減する、はるか関数として全てのPython中置演算子を提供します。(非常に多くの著者はラムダ関数好きではない理由を私は知りません)

好ましくは、後者のオブジェクトが反復を減らす可能性がある場合ので、最後のパラメータの初期化子を低減する初期値が与えられている、唯一の要素です。

だから、+、|、^ 0初期値は、設定されている(プラス、OR、XOR)

*&1の初期値を計算する(乗算、中)

要素は、非常に長い遅すぎる__eq__また、2つのリストコントラストいるので、途中で変更。

 デフ __hash__ (自己):
         戻り functools.reduce(XOR、(ハッシュ(I)のための I self._components)、0)

    DEF  __eq__ (分身):
         リターンでlen(セルフ)==(その他)でlen すべての(A == B のために A、B ZIPその他(セルフ))
        この書き込みは非常に美しいです、最初のlen決定し、中各要素内の分析、我々は短絡原則Pythonのに使用されています

初期値を満たしていない、operator.xor内部で使用されるテストコードを削減しても問題ありません。本が満たされていません。

 

itertoolsはzip_longest関数の内部機能をzip圧縮、または非常に興味深い、テストの下に来ます。

[5]:itertoolsからzip_longestインポート                                                 

[6]:リスト(zip_longest(範囲(1,4)、 'ABC'、[5,4,3,2,1]、))                                  
OUT [6]:[(1 ''、5)、(2、 'B'、4)、(3、 'C'、3)、(なし、なし、2)、(なし、なし、1 )]

[7]:リスト(zip_longest(範囲(1,4)、 'ABC'、[5,4,3,2,1]、fillvalue = -1))                      
OUT [7]:[(1 ''、5)、(2、 'B'、4)、(3、 'C'、3)、(-1、-1、2)、(-1、 -1、1)]

[8]で:リスト(ZIP(範囲(1,4)、 'ABC'、[5,4,3,2,1]、))                                          
OUT [8]:[(1 ''、5)、(2、 'B'、4)、(3、 'C'、3)]

 不足している、デフォルトはNoneであれば、最長繰り返しオブジェクトパッケージに従います、またデフォルトパラメータのfillvalueを埋めるために使用することができます。

 

10.7format出力

私がいない上、あまり忘れていくつかの数式、数学の使用に起因します。

おすすめ

転載: www.cnblogs.com/sidianok/p/12113537.html