オブジェクト指向6.9:メタクラス、反射、方法ビス
元类:
print(type('abc')) print(type(True)) print(type(100)) print(type([1, 2, 3])) print(type({'name': '太白金星'})) print(type((1,2,3))) print(type(object)) class A: pass print(isinstance(object,type)) print(isinstance(A, type))
型メタクラスはオブジェクトを取得することであるクラスに属し、そして特別なクラスを入力し、Pythonの原理は次のとおりです。すべてが対象で、実際には、クラスもまた、クラスを構築するためにクラスとタイプ元として知られている「オブジェクト」、Pythonの過半数として理解することができます(オブジェクトを含む)組み込みクラスだけでなく、クラスの独自の定義は、型メタクラスによって作成されます。
と型クラスと、より固有のオブジェクトクラスとの関係:オブジェクトは、クラス型のインスタンスであり、型がオブジェクトクラスのクラスのサブクラスであり、関係の比較は、Pythonマジック前さらに必須として定義されているコードに使用することができない表現しましたそれは存在しています。だから、これだけ理解として。
リフレクション:
手段を反映して、状態自体や行動(イントロスペクション)を検出し、修正する能力をプログラムにアクセスすることができます
パイソンリフレクティブなオブジェクト指向型:文字列によって操作オブジェクトに関連するプロパティ。すべてはPythonでオブジェクトである(あなたはリフレクションを使用することができます
一般的に使用される4つの機能を反映:
class Student: f = '类的静态变量' def __init__(self,name,age): self.name=name self.age=age def say_hi(self): print('hi,%s'%self.name) obj=Student('alex',16) # hasatter 检测是否含有某属性,方法 print(hasattr(obj,'name')) print(hasattr(obj,'say_hi')) 结果: True True # 获取属性,方法 # 获取不到直接报错 n=getattr(obj,'name') print(n) func=getattr(obj,'say_hi') func() 结果: 'alex' 'hi,alex' # 设置属性 setattr(obj,'sb',True) setattr(obj,'show_name',lambda self:self.name+'sb') print(obj.__dict__) print(obj.show_name(obj)) 结果: {'name': 'alex', 'age': 16, 'sb': True, 'show_name': <function <lambda> at 0x00000180E591BB70>} alexsb # 删除属性 delattr(obj,'age') # delattr(obj,'show_name') # delattr(obj,'show_name111')#不存在,则报错 print(obj.__dict__) 结果: {'name': 'alex'}
クラスリフレクション:
class Foo(object): staticField = "old boy" def __init__(self): self.name = 'wupeiqi' def func(self): return 'func' @staticmethod def bar(): return 'bar' print(getattr(Foo, 'staticField')) print(getattr(Foo, 'func')) print(getattr(Foo, 'bar')) # 结果: old boy <function Foo.func at 0x00000212D21FBC80> # 获取func对象方法地址 <function Foo.bar at 0x00000212D21FBD08> # 获取bar静态方法地址
これは、現在のモジュールを反映しました:
import sys def s1(): print('s1') def s2(): print('s2') this_module = sys.modules[__name__] print(hasattr(this_module, 's1')) print(getattr(this_module, 's2')) # 结果: True <function s2 at 0x000002000247BBF8>
その他のモジュールを反映:
import time print(hasattr(time,'ctime')) print(getattr(time,'ctime')) print(getattr(time,'ctime')()) # 结果: True <built-in function ctime> 'Fri Aug 9 08:12:54 2019'
反射したアプリケーション
# 没学反射之前的解决方式: class User: def login(self): print('欢迎来到登录页面') def register(self): print('欢迎来到注册页面') def save(self): print('欢迎来到存储页面') while 1: choose = input('>>>').strip() if choose == 'login': obj = User() obj.login() elif choose == 'register': obj = User() obj.register() elif choose == 'save': obj = User() obj.save()
差分法と機能:
印刷機能(メソッド)の名前で決定
def func(): pass print(func) # <function func at 0x00000260A2E690D0> class A: def func(self): pass print(A.func) # <function A.func at 0x0000026E65AE9C80> obj = A() print(obj.func) # <bound method A.func of <__main__.A object at 0x00000230BAD4C9E8>>
モジュールの種類によって検証
from types import FunctionType from types import MethodType def func(): pass class A: def func(self): pass obj = A() print(isinstance(func,FunctionType)) # True print(isinstance(A.func,FunctionType)) # True print(isinstance(obj.func,FunctionType)) # False print(isinstance(obj.func,MethodType)) # True
静的メソッドは、関数であります
from types import FunctionType from types import MethodType class A: def func(self): pass @classmethod def func1(self): pass @staticmethod def func2(self): pass obj = A() # 静态方法其实是函数 print(isinstance(A.func2,FunctionType)) # True print(isinstance(obj.func2,FunctionType)) # True
関数およびメソッドとの間の差
(1)関数は、この方法は、暗黙のパラメータ渡して、支配的なパラメータの受け渡しです。
(2)関数はオブジェクトとは何の関係もありません。
内部クラスの動作データの(3)の方法。
(4)メソッドは、オブジェクトに関連付けられています。
ダブルダウン方式:
定義:ダブルダウンは特別な方法であり、彼はメソッド名が提供するインタプリタプラスダブル二重下線のアンダースコアで__メソッド名は、特別な意味を持っている__方法、方法はでは、のpython-ソースプログラマーをダブルダウンすることですデュアル方式の下で開発を使用しないようにしよう、二重下線知られている方法は、私たちは、ソースコードを学ぶ手助け
1、のみ
class B: def __len__(self): print(666) b = B() len(b) # len 一个对象就会触发 __len__方法。 class A: def __init__(self): self.a = 1 self.b = 2 def __len__(self): return len(self.__dict__) a = A() print(len(a))
2、ハッシュ
class A: def __init__(self): self.a = 1 self.b = 2 def __hash__(self): return hash(str(self.a)+str(self.b)) a = A() print(hash(a))
3、STR
クラスは__str__メソッドが定義されている場合、場合印刷対象は、この方法は、デフォルトの出力値を返します。
class A: def __init__(self): pass def __str__(self): return '太白' a = A() print(a) print('%s' % a)
4、のrepr
クラスは__repr__方法が定義されている場合、その後のrepr(オブジェクト)には、この方法は、デフォルトの出力値を返します。
class A: def __init__(self): pass def __repr__(self): return '太白' a = A() print(repr(a)) print('%r'%a)
5、コール
オブジェクトの背後にあるブラケットには、実行をトリガ。
注:コンストラクタは、すなわち、__new__は、オブジェクトを作成するためにトリガされて実行される:クラス名=オブジェクト();についての呼び出しオブジェクトのメソッドによって実行されるブラケットをトリガする、即ち:オブジェクト()またはクラス()( )
class Foo: def __init__(self): pass def __call__(self, *args, **kwargs): print('__call__') obj = Foo() # 执行 __init__ obj() # 执行 __call__
6、EQ
class A: def __init__(self): self.a = 1 self.b = 2 def __eq__(self,obj): if self.a == obj.a and self.b == obj.b: return True a = A() b = A() print(a == b)
7、
オブジェクトがメモリにリリースされたデストラクタは、自動的に実行をトリガ。
され、この作業を実行するPythonインタプリタにあるので、この方法では、Pythonは高レベルの言語であるので、心配しないで使用プログラマが割り当て、空きメモリ、一般的に定義する必要はありませんので、デストラクタを呼び出します。注意してくださいそれは自動的にインタプリタによる時間のガベージコレクタで実行トリガ。
class A: def __init__(self): self.x = 1 print('in init function') def __new__(cls, *args, **kwargs): print('in new function') return object.__new__(A, *args, **kwargs) a = A() print(a.x)
8、新しいです
class A: def __init__(self): self.x = 1 print('in init function') def __new__(cls, *args, **kwargs): print('in new function') return object.__new__(A, *args, **kwargs) a = A() print(a.x)
シングルトン:
class A: __instance = None def __new__(cls, *args, **kwargs): if cls.__instance is None: obj = object.__new__(cls) cls.__instance = obj return cls.__instance
Singletonパターンは、一般的なソフトウェアのデザインパターンです。そのコア構造にのみ単一の実施形態は、特定のクラス分類と呼ばれる含有します。インスタンス数の制御を容易にし、システムリソースを節約するように例では、シングルモードシステムのみ1つのクラスインスタンスのインスタンスと外部への容易なアクセスを保証します。あなたが唯一のいずれかを指定でき、システム内のオブジェクトのクラスをしたい場合は、シングルトンパターンが最適なソリューションです。
[シングルケースモデル動機は、理由]
働いているシステムの特定のタイプのためには、一つだけのインスタンスは、例えば、システムが複数の印刷ジョブを含むことができるが、唯一の仕事を持つことができることが重要である。システムのみあなたは、ウィンドウマネージャやファイルシステムを持つことができ、システムは、タイミングデバイスまたはID(番号)発電機を持つことができます。Windowsのと同じように、あなただけのタスクマネージャを開くことができます。あなたは一意のウィンドウオブジェクトのメカニズムを使用しない場合は、複数のウィンドウがポップアップし、これらのウィンドウの内容はまったく同じを表示する場合、それは重複したオブジェクト、メモリリソースの無駄であり、一貫性のないコンテンツウィンドウが表示されている場合、それは一瞬にしていることを意味し、システムは、実際と矛盾する複数の状態を有し、誤解がユーザーにもたらすでしょう、私たちは本当の状態である1かわかりません。だから、時々 、クラス唯一のインスタンスであるオブジェクトの一意性を確保するためのシステムは非常に重要です。
唯一のクラスのインスタンス、およびこのインスタンスがそれにアクセスすることは容易であることを確認するには?グローバル変数を定義することは、オブジェクトがいつでもアクセスできることを確認することができますが、私たちは複数のオブジェクトをインスタンス化防ぐことはできません。よりよい解決策は、それを保存するための責任を負うクラス自体のインスタンスのみをさせることです。このクラスは、他のインスタンスが作成されないようにすることができ、そしてそれは、インスタンスにアクセスするための方法を提供することができます。これは、モチベーションモードSingletonパターンです。
[シングルトン]長所と短所
[利点]
まず、制御インスタンス
Singletonパターンは、すべてのオブジェクトが一意のインスタンスへのアクセスを有することを確実にするように、他のオブジェクトは、それ自身のシングルトンオブジェクトのコピーをインスタンス化防止します。
第二に、柔軟性を
コントロールクラスのインスタンス化プロセスので、そのクラスのインスタンス化のプロセスを変更するための柔軟性。
【欠点】
まず、オーバーヘッド
少数であるが、しかし、まだいくつかのオーバーヘッドを必要とするすべてのオブジェクト・リクエスト・参照する場合、クラスのインスタンスがあるかどうかを確認します。初期化は、静的を使用することによって、この問題を解決することができます。
第二に、混乱の可能性のある開発は、
シングルトンオブジェクト(クラスライブラリで定義され、特にオブジェクト)を使用する場合、開発者は、オブジェクトをインスタンス化する新しいキーワードを使用できないことを心に留めておく必要があります。それは、ライブラリのソースコードにアクセスすることはできませんので、アプリケーション開発者が直接インスタンス化することはできませんが予期せずに自分自身を見つけるかもしれないので。
第三に、オブジェクトの有効期間は、
問題は、単一のオブジェクトを削除解決することはできません。それはインスタンスプライベートへの参照が含まれているため、メモリ管理言語を提供する(例えば、.NETフレームワークの言語に基づいて)、クラスの実施形態の単一インスタンスのみをもたらすことができることは割り当てられていません。いくつかの言語(例えば、C ++)で、他のクラスのインスタンスオブジェクトを削除することができ、これは参照の懸濁液につながるシングルトン現れます** 9、__item__シリーズ**
class Foo: def __init__(self,name): self.name=name def __getitem__(self, item): print(self.__dict__[item]) def __setitem__(self, key, value): self.__dict__[key]=value def __delitem__(self, key): print('del obj[key]时,我执行') self.__dict__.pop(key) def __delattr__(self, item): print('del obj.key时,我执行') self.__dict__.pop(item) f1=Foo('sb') f1['age']=18 f1['age1']=19 del f1.age1 del f1['age'] f1['name']='alex' print(f1.__dict__)
10関連のコンテキストマネージャ
入力 終了を
# 如果想要对一个类的对象进行with as 的操作 不行。 class A: def __init__(self, text): self.text = text with A('大爷') as f1: print(f1.text)
class A: def __init__(self, text): self.text = text def __enter__(self): # 开启上下文管理器对象时触发此方法 self.text = self.text + '您来啦' return self # 将实例化的对象返回f1 def __exit__(self, exc_type, exc_val, exc_tb): # 执行完上下文管理器对象f1时触发此方法 self.text = self.text + '这就走啦' with A('大爷') as f1: print(f1.text)
カスタムファイルマネージャ
class Diycontextor: def __init__(self,name,mode): self.name = name self.mode = mode def __enter__(self): print("Hi enter here!!") self.filehander = open(self.name,self.mode) return self.filehander def __exit__(self,*para): print("Hi exit here") self.filehander.close() with Diycontextor('py_ana.py','r') as f: for i in f: print(i)
関連インタビューの質問:
class StarkConfig: def __init__(self,num): self.num = num def run(self): self() def __call__(self, *args, **kwargs): print(self.num) class RoleConfig(StarkConfig): def __call__(self, *args, **kwargs): print(345) def __getitem__(self, item): return self.num[item] v1 = RoleConfig('alex') v2 = StarkConfig('太白金星') # print(v1[1]) # print(v2[2]) v1.run() ------- class UserInfo: pass class Department: pass class StarkConfig: def __init__(self, num): self.num = num def changelist(self, request): print(self.num, request) def run(self): self.changelist(999) class RoleConfig(StarkConfig): def changelist(self, request): print(666, self.num) class AdminSite: def __init__(self): self._registry = {} def register(self, k, v): self._registry[k] = v site = AdminSite() site.register(UserInfo, StarkConfig) # 1 # obj = site._registry[UserInfo]() # 2 obj = site._registry[UserInfo](100) obj.run() ------- class UserInfo: pass class Department: pass class StarkConfig: def __init__(self,num): self.num = num def changelist(self,request): print(self.num,request) def run(self): self.changelist(999) class RoleConfig(StarkConfig): def changelist(self,request): print(666,self.num) class AdminSite: def __init__(self): self._registry = {} def register(self,k,v): self._registry[k] = v(k) site = AdminSite() site.register(UserInfo,StarkConfig) site.register(Department,RoleConfig) for k,row in site._registry.items(): row.run() ------- class A: list_display = [] def get_list(self): self.list_display.insert(0,33) return self.list_display s1 = A() print(s1.get_list()) ------- class A: list_display = [1, 2, 3] def __init__(self): self.list_display = [] def get_list(self): self.list_display.insert(0, 33) return self.list_display s1 = A() print(s1.get_list()) ------ class A: list_display = [] def get_list(self): self.list_display.insert(0,33) return self.list_display class B(A): list_display = [11,22] s1 = A() s2 = B() print(s1.get_list()) print(s2.get_list())