three.mdを学習するPython3エントリ

[ TOC]

10. Pythonファイルの操作と処理###

PythonでのFILEファイルの最も重要なメソッドはopen()メソッドZです。これは、ファイルを開いてファイルオブジェクトを返すために使用されます。この関数はファイルを処理するために必要です。

open(file, mode='rt')  #デフォルトはテキストモードの読み取り専用オープンです,バイナリモードで開きたい場合,追加b。
open(file, mode='rt',[buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None])  #完全な文法

# パラメータ説明:
file:必須,ファイルパス(相対パスまたは絶対パス)。
mode:オプション,ファイルオープンモード
buffering:セットバッファ
encoding:通常はutf8を使用します
errors:エラーレベル
newline:ニューラインを区別する
closefd:着信ファイルパラメータタイプ

# ファイルを開くことができない場合,OSErrorをスローします
# Fileオブジェクトのメソッドは、メモのPython3組み込み関数を参照しています

10.1 Pythonファイルシステム####

Pythonを使用してファイルを開き、コンテンツを読み取り、コンテンツを書き込みます。中国語の文字の書き込みに注意を払う必要があります*(utf-8エンコーディングを選択)*

#! /usr/bin/python3
# coding:utf-8
# 原則:ファイルシステム

# /****ケース1:ファイルコンテンツのトラバーサル***/
file =open('python.txt','r+',encoding='utf-8')

# 次の方法でファイルの内容を出力することはお勧めしません。;
# file.seek(0,0)
# lines =list(file)
# for eachline in lines:
#  print(eachline,end="")
# 別の方法では、ファイルオブジェクトメソッドを直接採用します(推奨)

print("ファイル記述子は: %d"%file.fileno())print("端末に接続するかどうか",file.isatty())

file.seek(0,0)for eachline in file:print(eachline,end="")
file.close()

# /****ケース2:ファイルコンテンツの分割***/
def save_file(boy,girl,count):
 file_name_boy ='boy_'+str(count)+'.txt'
 file_name_girl ='girl_'+str(count)+'.txt'

 afile =open(file_name_boy,'w',encoding='utf-8')  #コーディングの記述に注意してください
 bfile =open(file_name_girl,'w',encoding='utf-8')  

 afile.writelines(girl)
 bfile.writelines(boy)

 afile.close()
 bfile.close()

def split_file(filename):
 f =open(filename,'r',encoding='utf-8') #コーディングを読むことに注意してください
 Aauthor =[]
 Bauthor =[]
 count =1for lines in f:if lines[:6]!='======':(role,spoken)= lines.split(':')if role =='A':
    Aauthor.append(spoken) #リスト追加
   elif role =='B':
    Bauthor.append(spoken)else:save_file(Bauthor,Aauthor,count)
   # Re-A/Bを空のリストに設定します
   Aauthor =[]
   Bauthor =[]
   count +=1

 # ループの終了後、ファイルの保持が必要です,二度だけだから'======',初心者は間違いやすい
 save_file(Bauthor,Aauthor,count)  #キーポイント
 f.close()split_file('demo2-10.txt')

########################### 試験結果########################################
# C:\Users\Administrator\Desktop\Python\2>python demo2-10.py
# ファイル記述子は:3
# 端末デバイスに接続するかどうかFalse
# #1 :テスト
# #2: nAME = wEIYIgeek
# #3 :password =123456

10.2 Pythonファイル書き込み逆シリアル化####

説明:さまざまなpythonデータタイプをバイナリ形式でディスクに保存します。これは、データベースの逆シリアル化と同等です。読み取りおよび読み取り操作のために、pickleパッケージをインポートする必要があります。

pickleの本質は、いくつかのアルゴリズムを使用してデータオブジェクトをバイナリファイルに「選択」し、ディスクに保存することです。もちろん、データベースに配置したり、ネットワーク経由で別のコンピューターに転送したりすることもできます。

#! /usr/bin/python3
# 機能:データのシリアル化(バイナリ)import pickle
import os

value = dict.fromkeys((1,2,3,5,6),'pickle')print(value)
def pkldown(filename):if os.path.exists(filename):print("ファイルはすでに存在し、開いています",end="")
  f =open(filename,'wb')else:
  f =open(filename,'wb')

 pickle.dump(value,f)
 f.close()

def pklget(filename):
 f =open(filename,'rb')
 getv = pickle.load(f)  #最初に使用することに注意してください'rb'ファイルを開く
 f.close()print(" %s "%getv)pkldown('test.pkl')pklget('test.pkl')

WeiyiGeek.open関数モード属性パラメーター

注:pickleを使用して「* .txt」タイプのファイルとして保存しますが、バイナリファイルとして保存し、直接開くと文字化けします。

11. Pythonエラーと例外スロー###

例外処理メカニズムの重要性を要約します。
環境の不確実性やユーザー操作の予測不可能性により、プログラムでさまざまな問題が発生する可能性があります。したがって、最も重要な例外メカニズムは、プログラムとユーザーエクスペリエンスの堅牢性を強化し、予測されるすべての例外を可能な限りキャプチャすることです。処理コードを記述します。例外が発生すると、プログラムは自動的にダイジェストして通常に戻ります(クラッシュしない)。

ステートメント構文を試してください:

try:
 検出されたコードブロック
execpt Exception [as reaon]:
 例外後に実行されたコード
else:
 異常が発生しない場合,elseのステートメントが実行されます

try-finallyステートメント:

try:
 検出されたコードブロック
execpt Exception [as reaon]:
 例外後に実行されたコード
else:
  異常が発生しない場合,elseのステートメントが実行されます
finally:
  何があっても実行されるコード

# raiseステートメントは例外をスローします
システム例外名を上げる('間違った説明')

# ステートメントフォローファイルI/O自動リリース(手動でリリースする必要はありません),ステートメントが複数のアイテムを処理する場合,カンマで区切った文として書くことができます)e
withopen('data.txt','w')ファイルオブジェクトとして:
# 場合
withA()as a,B()as b:
 suite

エラーと例外スローの場合:

#! /usr/bin/python3
# プログラムの例外処理

# ケース1:どんな種類のエラーでも、処理コードが実行されます
try:
 sum =1+'a'
except:print("プログラムにエラーBUGがあります, [この方法は実際には推奨されません]")

# インストール2:指定された例外が指定された操作を実行します
try:
 f =open('noexsitfile.txt')  #ここで実行して、OSerror例外実行応答コードに直接ジャンプします
 print("----------------------")
 f.write("私は存在します")
 sum =1+'b'
except OSError as err:print("OSError:",str(err))
except TypeError as err:print("TypeError:",str(err))print("----------------------")

# ケース3:同じ例外処理コードを実行するために異なる例外を指定する,最終的に、例外がスローされない場合に実行されます
try:
 f =open('noexsitfile.txt','w',encoding='utf-8')  #ここで実行して、OSerror例外実行応答コードに直接ジャンプします
 print(f.write("私は存在します"))
 sum =1+'b'except(OSError,TypeError)as identifier:print("プログラムが異常です:",str(identifier))finally:print("例外をスローするかどうかに関係なく、開いているファイルを閉じます")
 f.close()print("-------------------------")

# ケース4:指定された例外をスローする
try:if'a'>'b':
  raise TypeError("私たちは異常です")else:
  raise NameError("異常になります")  #指定された例外をスローします
except(TypeError,NameError)as errvalue:print("カスタム例外理由:",errvalue)print("-------------------------")
# ケース5:試してみてください....except...else...最後に声明,異常が発生しない場合,elseのステートメントが実行されます
try:print(1/2)
except TypeError as identifier:print("間違った理由:",str(identifier))else:print("例外なく実行します")finally:print("何が悪いのか実行しなければならない")print("----------------------")
# 言語を使用したケース6
try:withopen('with.txt','w',encoding='utf-8')as f:
  f.write("Test ... Test")print("完全なファイル書き込み")
except OSError as reson:print("何かがうまくいかなかった",str(reson))else:print("何も間違ってない,開いているファイルは自動的に閉じられます")

WeiyiGeek。エラーと例外スローのケース

def file_compare(file1, file2):withopen(file1)as f1,open(file2)as f2:  #学ぶ価値がある
  count =0 #統計行
  differ =[] #異なる数を数える

  for line1 in f1:
   line2 = f2.readline()
   count +=1   #ファイル機能の比較
   if line1 != line2:
    differ.append(count)return differ

file1 =input('比較する最初のファイル名を入力してください。')
file2 =input('比較する別のファイル名を入力してください。')

differ =file_compare(file1, file2)iflen(differ)==0:print('2つのファイルはまったく同じです!')else:print('2つのファイルが共有されます[%d]異なる:'%len(differ))for each in differ:print('最初%dは同じではありません'% each)

12. Pythonオブジェクト指向###

OOPの考え:

オブジェクト指向のいくつかの機能:

  1. カプセル化:外部の隠しオブジェクトの作業の詳細
  2. 継承:サブクラスが親クラス間でデータとメソッドを自動的に共有するためのメカニズム(サブクラスは親クラスから継承します)
  3. 多態性:異なるタイプのオブジェクトで同じメソッドを呼び出して、異なる結果を生成できます(異なるオブジェクトは同じメソッドに対する異なるアクションに応答します)

WeiyiGeek。クラス/クラスオブジェクトとインスタンスオブジェクト

クラスの属性とメソッド

classTest:
 count =0  #静的プロパティ
 public_attrs =0 #公共財産
 __ private_attrs =0 #民間

 def __init__(self):
  C.count = C.count +1  #クラス名.属性名フォーム参照(すべてのインスタンス化+1)

 def prt(self):print('これはパブリックメソッドです')  #パブリックメソッド
  print(self)print(self.__class__)
  self.__foo()   #プライベートメソッドを呼び出す

 def __foo(self):          #プライベートメソッド
  print('これは私的な方法です')
    
 def getCount(self):return C.count   #クラスの静的プロパティの適用(クラスがインスタンス化された回数をカウントします)
        
t =Test()
t.prt()

# 注意#
t._Test__private_attrs  #外部から直接私有地に電話する
t._Test__foo()          #外部から直接プライベートメソッドを呼び出す

############### 上記の例の実行結果は次のとおりです。#############################
# これはパブリックメソッドです
# <__ main__.Test instance at 0x100771878>  #selfはクラスのインスタンスを表します,現在のオブジェクトのアドレスを表します
# __ main__.Test  #self.クラスはクラスを指します
# これは私的な方法です
# これは私的な方法です#外部から呼び出されるプライベートメソッド

12.1 パッケージ####

オブジェクトパッケージケース:

#! /usr/bin/python3
# オブジェクトとタイプをインスタンス化します

# ケース1:パッケージの特性
classPerson:
 name ='WeiyiGeek'    #属性
 age =20
 msg ='I Love Python'
 # プライベート属性を定義する,クラス外から直接プライベートプロパティにアクセスすることはできません
 __ weight =120
 def printname(self):  #方法
  print(self.name,self.age,self.msg,self.__weight)

people =Person()   #インスタンス化
people.printname()  #オブジェクト.方法

# Pythonは実際には「名前マングリング」と呼ばれるテクノロジーを使用しています,二重下線で始まる変数名は巧妙に変更されました。,私たちはまだ「_クラス名__変数名」アクセス:
print("体重:",people._Person__weight,'KG')

# ケース2:パッケージの特性
classRectangle:
 length =5
 width =6
 # 長さと幅を設定する
 def setRect(self,length,width):
  self.length = length
  self.width = width
    
 # 長さと幅を取得する
 def getRect(self):print("長方形の長さと幅は次のとおりです。%d , %d"%(self.length,self.width))
    
 # エリアを取得
 def getArea(self):print("長方形の領域=",self.width * self.length)

 # 周囲を取得します
 def getGirth(self):print("長方形の円周=",2*(self.width + self.length))

rect =Rectangle()
rect.setRect(15,16)
rect.getRect()
rect.getArea()
rect.getGirth()

############ の結果##############
# WeiyiGeek 20 I Love Python 120
# 体重:120 KG
# 長方形の長さと幅は次のとおりです:15,16
# 長方形の領域=240
# 長方形の円周=62

12.2 継承####

継承された検索:

WeiyiGeek。継承された検索

継承構文:

クラスサブクラス名(基本クラス,お父さん,またはスーパークラス名)

場合:

#! /usr/bin/python3
# オブジェクトとタイプをインスタンス化します

# ケース1:単一継承の例
# お父さん
classPerson:
 name =''     #基本的な属性を定義する
 __ UID =0     #私有財産
 # 魔法の方法
 def __init__(self,*args):
  self.name = args[0]
  self.__UID = args[1]
 # クラスメソッド
 def speak(self):print("%sのID番号は%d"%(self.name,self.__UID))

# サブクラス
classStudent(Person):
 grade =''
 def __init__(self,*args):
  # 親クラスのコンストラクターを呼び出す
  Person.__init__(self,args[0],args[1])
  self.grade = args[2]
 # 親クラスのspeakメソッドをオーバーライドします
 def speak(self):print("名前:%s ,グレード:%s ,識別番号%d親クラスのプライベート変数であるため、このようにselfを呼び出すことはできません。._Person__UID "%(self.name,self.grade,Person._Person__UID))  

xs =Student('WeiyiGEEK',512301031998010937,'2018年のクラス')
xs.speak()

## ケース2:複数の継承
# 次のコード,クラスA,Bは異なる機能単位を表します,CはAです,B機能の組み合わせ,这样类C就拥有了クラスA,Bの機能。
classA:
 def get_a(self):
 print 'a'classB:
 def get_b(self):
 print 'b'classC(A, B): #クラスCはクラスAです/カテゴリBのサブカテゴリ
 pass

c =C()
c.get_a()
c.get_b()

## ケース3:動的継承の基本クラスは動的です(場合によってはA、場合によってはB)
## 実装:最初に基本クラスのエイリアスを定義します。クラスを定義するときは、エイリアスを使用して、継承する基本クラスを置き換えます。
BaseAlias = BaseClass  #エイリアス基本クラス

classDerived(BaseAlias): #このパラメータは基本クラスのエイリアスであることに注意してください
 def meth(self):
  BaseAlias.meth(self)  #エイリアスを介して基本クラスにアクセスする
        ...

############################## の結果################################
# 名前:WeiyiGEEK,グレード:2018,ID番号0は、親クラスのプライベート変数であるため、次のように呼び出すことはできません。._Person__UID
# a
# b
#

( 補足):組み合わせの紹介* Q:組み合わせ(構成)とは何ですか? *
回答:Pythonの継承メカニズムは非常に便利ですが、コードを複雑にし、暗黙の継承に依存するのは簡単です。多くの場合、代わりに組み合わせを使用できます。 Pythonでの結合は実際には非常に簡単で、必要なクラスをクラス定義に直接入れてインスタンス化します

簡単に言えば、「has one」シーンではコンポジションが使用され、「isone」シーンでは継承が使用されます。

#* クラスの組み合わせ(水平)*#
# タートルズ
classTurtle:
 def __init__(self, x):
  self.num = x
        
# 魚類
classFish:
 def __init__(self, x):
  self.num = x

# プールクラス
classPool:
 def __init__(self, x, y):
  self.turtle =Turtle(x)    #コンビネーションタートルが登場(要点)
  self.fish =Fish(y)        #パスに入る魚の組み合わせ(要点)
     
 def print_num(self):print("プールには全部でカメがいます%dのみ,小魚%d!"%(self.turtle.num, self.fish.num))>>> pool =Pool(1,10)>>> pool.print_num()

(補足):super()スーパークラス
Pythonでは、メソッドを呼び出す前にインスタンスが必要です。この制限は、実際にはPythonのいわゆるバインディングの概念です。

#! /usr/bin/python3
# 機能:スーパースーパークラスの実装
import random as r  #エイリアス

classFish:
 def __init__(self):
  self.x = r.randint(0,10)
  self.y = r.randint(0,10)
    
 def move(self):
  self.x -=1print("私の立場は:",self.x,self.y)classShark(Fish):
 def __init__(self):super().__init__()        #方法1:スーパーを設定するだけでよい()親クラスを参照します
  # Fish.__init__(self)      #方法2:親クラスコンストラクターを呼び出す
  self.hungry = True
 def eat(self):if self.hungry:print("空腹,食べたいです@!")
   self.hungry = False
  else:print("協力的すぎる,食べられない")

demo1 =Shark()
demo1.move()
demo1.eat()
demo1.eat()
demo1.move()

######### の結果########
# 私の立場は:05
# 空腹,食べたいです@!
# 協力的すぎる,食べられない
# 私の立場は:-15

12.3 多形性####

12.4 魔法の方法####

魔法の方法が具体化されており、適切なタイミングでいつでも自動的に呼び出すことができます。
(0) **new **(cls [、…])#最初にマジックメソッドを実行します。不変の型を継承しているが変更する必要がある場合、通常はクラスのインスタンス化されたオブジェクトを返します。
(1) init(self[,…])
(2) **del **(self)#Garbage収集メカニズム、C ++のdestructorメソッドに似ています

(3) **add **(self、other)#Magic methodcalculation-その他は類似しています
(4) および(self、other)#Magicメソッド論理演算子

(5) **radd **(self、other)#a + bなどのマジックメソッドリバース操作。オブジェクトが+操作をサポートしていない場合は、bの処理スキームを使用して追加します。
(6) **rsub **(self、other)#魔法の方法は上記と同じです

(7) **str **(self)#文字列を出力する必要がある場合は、印刷出力を使用する必要があります
(8) **repr **(self)#Stringは外部関数なしで直接出力されます

(9) **getattr **(self、name)#属性アクセスの魔法の方法。ユーザーが存在しない属性を取得しようとするタイミングを定義します。
(10) **getattribute **(self、name)#このクラスの属性にアクセスしたときの動作を定義します
(11) **setattr **(self、name、value)#属性が設定されたときの動作を定義します
(12) **delattr **(self、name)#属性が削除されたときの動作を定義します

(13) **get **(self、instance、owner)#descriptor、属性へのアクセスに使用され、属性の値を返します
(14) **set **(self、instance、value)#属性割り当て操作で呼び出され、何も返されません
(15) **delete **(self、instance)#削除操作を制御し、コンテンツを返します

(16) **len **()#コンテナはlen(object)メソッドで勝ち誇ってトリガーされています
(17) **getitem **()#辞書dict ['key']などのコンテナキー値が取得されたときにトリガーされます
(18) **setitem **()#辞書dict ['key'] = 1024など、コンテナ内の指定された要素の動作を設定します

ケース1:次の要件に従ってアミューズメントパークのチケットクラスを定義し、大人2名+子供1名の平日のチケット価格を計算してみます。オブジェクト指向のプログラミングの難しさは、考え方の変化にあります。

# 平日のチケット価格100元
# 週末の運賃は平日120です%
# 子供のためのハーフチケット

# ケース1:
classTicket():
  def __init__(self, weekend=False, child=False):
    self.exp =100if weekend:  #日曜日によると/計算する子供
      self.inc =1.2else:
      self.inc =1if child:  #子供の価格
      self.discount =0.5else:
      self.discount =1

  def calcPrice(self, num):return self.exp * self.inc * self.discount * num  #ここでの要点

adult =Ticket()
child =Ticket(child=True)print("大人2名+1人の子供のための平日の運賃は次のとおりです。%.2f"%(adult.calcPrice(2)+ child.calcPrice(1)))

# ケース2:
# オブジェクトをインスタンス化するとき,この変数+1,オブジェクトを破壊するとき,この変数自动-1)
classCount:
 count =0 
 def __init__(self):    #インスタンスの初期化
  Count.count +=1
 def __del__(self):     #デルコールは魔法のメソッドをトリガーします
  Count.count -=1
 def getCount(self):print("現在のカウント%d値"%Count.count)

a =Count() #initをトリガーします
b =Count()
c =Count()
d = a  #これがdのaへの参照です
e = a
print(Count.count)
del d  #注:delはここではトリガーされません(Delは、すべての参照が削除された後にのみトリガーできます)
del e  #ここでもトリガーできません
del a  #トリガーデル
print(Count.count)

# ケース3:
# CapStrは不変のクラスを継承します
classCapStr(str):
 def __new__(cls,string):
  string = string.upper()   #不変のタイプをサイズに変える
  return str.__new__(cls,string) #変更した文字をオブジェクトに返します

a =CapStr('I love Study Python3!')print(a)

############### の結果#################
# 2 大人+子供1名の平日料金:250.00
# 3
# 2
# I LOVE STUDY PYTHON3!

(2) クラスアルゴリズム操作マジックメソッド
説明:Py2.2より前は、クラスとタイプが分離されていました(実際には、クラスと属性のカプセル化)が、その後、作成者は統合しました(Pythonタイプをファクトリ関数に変換しました)。次に例を示します。
ファクトリ関数は実際にはクラスオブジェクトです。それらを呼び出すと、実際には対応するインスタンスオブジェクトが作成されます。

# 実際のエンジニアリング関数はクラスオブジェクトです
>>> type(len)<class'builtin_function_or_method'>  #内蔵機能

>>> type(int)   #タイプはすべてクラスオブジェクトです
< class'type'>>>>type(tuple)<class'type'>>>>classC:...  pass
...>>> type(C)  #クラス定義
< class'type'>
# Py2.2前
# int('123') #実際にはintと呼ばれ、整数値を返します
# py2.2の後
a =int('123')  #実際にはインスタンス化されたオブジェクトです

ケース2:

#! /usr/bin/python
# クラスマジックアルゴリズム操作の場合
# intクラスを継承する
classNewint(int):
 def __add__(self, value):returnsuper().__add__(value)  #スーパーはスーパークラスであり、親クラスを指します
 def __sub__(self, value):
  # returnsuper().__sub__(value) #方法1returnint(self)-int(value)  #方法2,ここで型変換を強制する必要があることに注意してください,以下に進むと、エラー再帰ループ例外が報告されます
  # return self - value   #RecursionError: maximum recursion depth exceeded in comparison
 def __and__(self, value):       #魔法の方法=&returnsuper().__and__(value)

a =Newint(8)
b =Newint(6)print("a + b =",a + b)print("a - b =",a - b)print("a & b =",a & b)

# ケース3:Pythonマジックメソッドの操作はCに似ています++オペレーターの過負荷
classint(int):
 def __add__(self,other):return int.__sub__(self,other)  #キーポイントの過負荷

a =int('5')
b =int('4')print("オペレーターの過負荷:+ b => a - b =", a + b)

######## 実行効果###########
# a + b =14
# a - b =2
# a & b =0
# オペレーターの過負荷:+ b => a - b =1

(3) クラス逆アルゴリズム計算マジックメソッド
場合:

#! /usr/bin/python
# ケース1:逆演算子
classNewint(int):
 def __radd__(self, value): #逆操作+return int.__sub__(value,self)  #方法1:実行は減算です。値の順序は、誰が減算されるかに影響します。/分

 def __rsub__(self, value):  #逆操作
  returnsuper().__add__(value)  #方法2:減算を実行する

 def __rmul__(self, value):returnsuper().__truediv__(value)

a =Newint(5)
b =Newint(3)print(a + b)  #オブジェクトaがサポートできるので+/-,したがって、逆の操作はトリガーされません
print(a - b)  

# 1は非オブジェクトなので、bの方法を使用します
print("1 + b =",1+ b)  #  1-3=>-2値の変更による,自己秩序
print("1 - b =",1- b)  #逆演算をトリガーします=>3+1=4print("1 * b =",5* b)  #逆演算をトリガーします=>3/5=0.6

# ケース2:単項演算子
classOneInt(int):
 def __pos__(self):  #負の符号の動作を定義する-x
  returnsuper().__pos__()  # -(self)

a =OneInt(-1)print("-(a) =",-a)   #この時点でUnary演算子がトリガーされます-(-1)

######### の結果########
# 8
# 2
# 1+ b =-2
# 1- b =4
# 1* b =0.6
# - ( a)=1

(4) クラスの補足魔法メソッド

#! /usr/bin/python
classDemo:
 def __str__(self):return'私は__str__魔法の方法,印刷が必要()出力'classDemo1:
 def __repr__(self):return'2 -私は__repr__魔法の方法,直接オブジェクト出力'
  
a =Demo()print("1 -",a)

b =Demo1()print(b)  #に>>>bは直接出力できます

################ の結果#################
# 1- 私は__str__魔法の方法,印刷が必要()出力
# 2- 私は__repr__魔法の方法,直接オブジェクト出力

(5) クラス属性アクセスマジックメソッド
クラス属性を介してメソッドを設定および呼び出します。

#! /usr/bin/python
# プロパティアクセスの魔法の方法

# 方法ケース1:
classAttrView:
 def __getattribute__(self, name):print("getattributeマジックメソッドを呼び出す")returnsuper().__getattribute__(name)  #super()基本クラスを自動的に取得します。このクラスには継承されたクラスがありません。デフォルトはオブジェクトクラスです。

 def __getattr__(self,name):print('getattrマジックメソッドを呼び出す')

 def __setattr__(self,name,value):print("setattrマジックメソッドを呼び出す")super().__setattr__(name,value)
    
 def __delattr__(self, name):print('delattrマジックメソッドを呼び出す')super().__delattr__(name)

demo =AttrView()
demo.x  #属性がない場合にgetattributeを呼び出すトリガー/getattr(トリガーなし)魔法の方法
setattr(demo,'x',1) #属性の設定はsetattrマジックメソッドを呼び出します
demo.y =1        #属性の設定はsetattrマジックメソッドを呼び出します
demo.y            #属性を取得するgetattributeマジックメソッドを呼び出す
delattr(demo,'y')  #属性の削除はdelattrマジックメソッドを呼び出します

# 方法ケース2:
classRectangle:
 def __init__(self, width =0, height =0):
  self.width = width   #トリガーします__setattr__魔法の方法
  self.height = height

 def __setattr__(self, name, value):if name =='square':  #平方
   self.height = value
   self.width = value
  else:super.__setattr__(self, name, value)   #方法1:無限の再帰エラーを防ぐ(基本クラスのsetattrメソッドを使用することをお勧めします)
   # self.__dict__[name]= value    #方法2

 def getArea(self):return self.width * self.height

 def getPeri(self):return(2*(self.width)+2*(self.height))

r1 =Rectangle(4,5)print("長方形の領域:",r1.getArea())

r1.square =10 #正方形であることを示す属性を作成します
print("スクエアエリア: ",r1.getArea())print("正方形の周囲:",r1.getPeri())print("__dict__",r1.__dict__)    #クラスのすべての属性を辞書タイプに戻します

########## の結果####################
# 長方形の領域:20
# スクエアエリア:100
# 正方形の周囲:40
# __ dict__ {'width':10,'height':10}

(6) カスタムシーケンスの魔法の方法
説明:プロトコルは他のプログラミング言語のインターフェースと非常に似ています。これらのメソッドを定義する必要があると規定されていますが、Pythonのプロトコルはそれほど正式ではありません。実際、更新はガイドです。

要件:変更できないカスタムリストを作成し、各要素がアクセスされた回数を記録します。

#! /usr/bin/python3
# 機能:コンテナシーケンスカスタムタイプ合意()
# - *- coding:utf-8-*-classCountnum:
 def __init__(self,*args):
  self.value =[x for x in args]  #リスト式
  self.count ={}.fromkeys(range(len(self.value)),0)

 def __len__(self):returnlen(self.value)

 def __getitem__(self,index):
  self.count[index]+=1return self.value[index]

a =Countnum(1,3,5,7,9)
b =Countnum(2,4,6,8,10)print(a[1],b[1])print(a[1],b[1])print("2つのオブジェクトシーケンスの合計:",a[3]+b[3])print("Aの訪問数:",a.count)print("オブジェクトBへの訪問数:",b.count)

############ の結果################
# $ python demo3.23.py
# 34
# 34
# 2つのオブジェクトのシーケンスの合計:15
# Aの訪問数:{0:0,1:2,2:0,3:1,4:0}
# オブジェクトBへの訪問数:{0:0,1:2,2:0,3:1,4:0}

12.5 ディスクリプタ####

説明:記述子は、特定のタイプのクラスのインスタンスを別のクラスのプロパティに割り当てることです。たとえば、property()は奇妙なBIFであり、プロパティとしてメソッドにアクセスするのに役立ち、より使いやすいアクセスメソッドを提供します。 ;

記述子はクラスであり、** get ()、 set ()、または delete **()の3つの特別なメソッドの少なくともいずれかを実装するクラスです。

#! /usr/bin/python
# クラス属性-ディスクリプタ

# クラスを定義する,元のプロパティの原則を実現するには、次の3つの魔法の方法を使用する必要があります
# ケース1classDecriptor:
 def __get__(self,instance,owner):print("getting ... ",self, instance, owner) #パラメータは(記述子自体,クラスオブジェクトテスト,テストクラス自体)

 def __set__(self,instance,value):print("setting ... ",self, instance, value)

 def __delete__(self,instance):print("deleting ...",self,instance)classTest:
 x =Decriptor()  #Decriptor()クラスのインスタンス/属性xと呼ばれる記述子

test =Test()
test.x
test.x ='ceshi'
del test.x 

############ の結果#######
# getting ...<__main__.Decriptor object at 0x000002443D18E908><__main__.Test object at 0x000002443D18E940><class'__main__.Test'>
# setting ...<__main__.Decriptor object at 0x000002443D18E908><__main__.Test object at 0x000002443D18E940> ceshi
# deleting ...<__main__.Decriptor object at 0x000002443D18E908><__main__.Test object at 0x000002443D18E940>

# ケース2:カスタムプロパティ
classMyProperty:
 def __init__(self, fget=None, fset=None,fdel=None):  #他のクラスの3つのメソッド
  self.fget = fget
  self.fset = fset
  self.fdel = fdel

 def __get__(self,instance,owner):return self.fget(instance)      #インスタンスオブジェクトを渡す方法

 def __set__(self,instance,value):
  self.fset(instance,value)
    
 def __delete__(self,instance):
  self.fdel(instance)classC:
 def __init__(self):
  self._x = None
    
 def getX(self):return self._x

 def setX(self, value):
  self._x = value

 def delX(self):print("破棄属性を削除します!")
  del self._x
    
 # xオブジェクトの記述子(クラスの3つのメソッドに渡します)
 x =MyProperty(getX,setX,delX)   #クラスインスタンス

c =C()
c.x ='Property'print(c.x,c._x)
del c.x

######################
# Property Property
# 破棄属性を削除します!

12.6 モディファイア(デコレータ)####

モディファイアはよく知られた設計パターンであり、アスペクト要件のあるシナリオでよく使用されます。より古典的なものには、ログの挿入、パフォーマンステスト、トランザクション処理などがあります。モディファイアを使用すると、多数の関数と関数関数を抽出できます。それ自体とは無関係であり、再利用され続ける同一のコード。
実際、モディファイアは洗練されたパッケージですが、関数はモジュールまたはクラス定義内でのみ変更でき、クラスは許可されないことに注意してください。モディファイアは、変更された関数をパラメータとして受け取る関数です。 、および同じ名前または他の呼び出し可能なものの変更された関数を返します。

1 )@修飾子の紹介と使用
Python関数では、関数定義の前の行が@functionNameで装飾されていることがあります。インタプリタが@のような修飾子を読み取ると、最初に@の後にコンテンツが解析され、関数が@またはの次の行に直接配置されます。 @の背後にある関数のパラメーターとしてクラス分けし、次の行で装飾されている関数オブジェクトに戻り値を割り当てます。

使用例:

#! /usr/bin/python
import time
 
##############################
classDemo(object):
 def __init__(self,foo):
  self.foo = foo
  self.foo()  #渡されたf関数を呼び出す

@ Demo  #F()関数はパラメーターとしてクラスに渡されます
def f():print("I love Python.org!")

# ケース1:funcA(funcB(func(4)))
def funcA(A):  #正式なパラメータに注意してください
 print("function A")

def funcB(B):print(B(2))  #B(2)実際にfuncでfuncに渡されました(2)sはcに同意します**2の値
 print("function B")

@ funcA
@ funcB
def func(c):print("function C")return c**2

######### の結果.START########
# I love Python.org!
# function C
# 4
# function B
# function A
######### の結果.END########

# ケース2:機能
def timeslong(func):  #funcパラメータ,修飾子の下にあります
 def call():
  start = time.perf_counter()print("It's time starting ! ")func()  #実際にはf関数(func()キーワードと同じです)
  print("It's time ending ! ")
  end = time.perf_counter()return"It's used : %s ."%(end - start)  #出力印刷
 return call

# 沿って@timeslongは目的を達成するためにそれを変更し、コード全体が美しく、コードのごく一部が美しい
@ timeslong  #最初にtimelongを実行し、次に呼び出してfuncを実行します=>f()
def func():
 y =0for i inrange(5):
  y = y + i +1print(y)return y

print(func())
######### の結果.START########
# It's time starting !
# 1
# 3
# 6
# 10
# 15
# It's time ending !
# It's used :0.006445216000000031.
######### の結果.END########

# ケース3.修飾子はクラスを通じても使用できます
classtimeslong1(object):
 def __init__(self,func):
  self.f = func  #実際の着信はfです()関数

 def __call__(self):
  start = time.perf_counter()print("It's time starting ! ")
  self.f()print("It's time ending ! ")
  end = time.perf_counter()print("It's used : %s ."%(end - start))

@ timeslong1  #次の関数またはクラスをパラメータとして使用します
def f():
 y =0for i inrange(3):
  y = y + i +1print(y)return y
 
f()  #呼び出されたときにトリガーされます@修飾子

######### の結果.START########
# It's time starting !
# 1
# 3
# 6
# It's time ending !
# It's used :0.00160638099999999.
######### の結果.END########

2) 組み込みの修飾子
クラスで定義されたインスタンスメソッドを静的メソッド(staticmethod)、クラスメソッド(classmethod)、およびクラスプロパティ(プロパティ)に変換するために使用される3つの組み込み修飾子があります。静的メソッドとクラスメソッドはあまり有用ではないことに注意してください。 。

#! /usr/bin/python3
# 機能:クラスメソッドを実装する/静的メソッド/クラス属性

classHello(object):
 def __init__(self):
  pass

 # 方法1.クラスメソッド
 @ classmethod
 def print_hello(cls):print("方法1:クラスメソッドprintを呼び出す_hello()",)

 # 方法2:静的メソッドとクラスメソッドの設定が非常に苛立たしいためです。そのため、Pythonの作成者は、関数修飾子を置き換える形式を開発しました。
 def foo(cls):print("方法2:クラスメソッドfooを呼び出す()")
 # fooになります()メソッドはクラスメソッドに設定されます
 foo =classmethod(foo)

 # 方法3:静的な方法(ここで巨大な穴の自己に注意してください)
 @ staticmethod
 def static_hello(arg):return"方法4:静的メソッドstaticを呼び出す_hello Value ="+str(arg)

 # 静的メソッドの比較

Hello.print_hello() #クラスメソッドを変更した後、_hello()クラスメソッドになり、Helloを直接渡すことができます.print_hello()インスタンスオブジェクトをバインドせずに呼び出します。
Hello.foo()print(Hello.static_hello(1),Hello.static_hello) #ここでパラメータを渡すことに注意してください

######### の結果################
# 方法1:クラスメソッドprintを呼び出す_hello()
# 方法2:クラスメソッドfooを呼び出す()
# 方法3:静的メソッドstaticを呼び出す_hello Value =1<function Hello.static_hello at 0x000001F2DB73C950>

# >>> c1 =Hello()
# >>> c2 =Hello()
# # 静的メソッドはメモリに1つだけ生成し、オーバーヘッドを節約します
# >>> c1.static_hello is C.static_hello       #True
# >>> c1.nostatic is C.nostatic   # False
# >>> c1.static_hello        # <function Hello.static_hello at 0x000001F2DB73C950>
# >>> c2.static _hello       # <function Hello.static_hello at 0x000001F2DB73C950>
# >>> Hello.static_hello     # <function Hello.static_hello at 0x000001F2DB73C950>

# # 通常のメソッドには、インスタンスごとに個別のオブジェクトがあり、コストがかかります
# >>> c1.nostatic   # <bound method  Hello.nostatic of<__main__.C object at 0x03010590>>
# >>> c2.nostatic  # <bound method  Hello.nostatic of<__main__.C object at 0x032809D0>>
# >>> Hello.nostatic   # <function  Hello.nostatic at 0x0328D2B8>

# ケース3:属性修飾子を使用して記述子を作成する」
classC:
 def __init__(self, size=10):
  self.size = size
        
 @ property   #キーポイント属性/バインドされたプロパティはxです
 def x(self):return self.size

 @ x.setter  #
 def x(self, value):
  self.size = value

 @ x.deleter
 def x(self):
  del self.size

demo =C()print("属性の値を取得します。",demo.x)      #属性の値を取得します。 10
demo.x =1024print("変更されたプロパティの値を取得します。",demo.x) #変更されたプロパティの値を取得します。 1024
del demo.x

Recommended Posts

three.mdを学習するPython3エントリ
Pythonエントリー学習教材
Four.mdを学習するPython3エントリ
Python3.mdの使用を開始する
two.mdを学習するPython3エントリ
Pythonエントリ-3
python学習ルート
パイソンリスト学習
03.Pythonエントリの演算子
Python関数の基礎学習
python_正規式学習
Pythonエントリチュートリアルノート(3)配列
Python正規表現クイックラーニング
PythonプログラミングPycharm高速学習
Pythonマジック関数eval()学習
05.Pythonエントリ値ループステートメント
Pythonの正規表現学習の小さな例
Pythonの3日目の1行関数の学習
Pythonエントリーノート[基本的な文法(下記)]
入門から習熟までのPython(2):Pythonの概要
パイソンクローラー開発の学習パス
Python学習OSモジュールと使用法
Pythonの基礎を学ぶ2日間