Pythonのリフレクティブなオブジェクト指向、方法ビス

反射

概念が最初に提案1982年スミスによって反射され、主にそれがプログラム缶アクセス、自身の状態や動作(イントロスペクション)を検出し、修正する能力を指します。これは、前方迅速コンピュータサイエンスの反射の応用に関する研究につながっコンセプトを置きます。これは、第一言語の設計をプログラミングの分野で使用された、とLispとオブジェクト指向の面で実績をあげています。

パイソンリフレクティブなオブジェクト指向:オブジェクトに関連するプロパティが文字列で動作しました。すべてが(リフレクションを使用することができる)Pythonでオブジェクトであります

四つの機能が内省的な達成することができます

以下の方法は、クラスおよびオブジェクトに適用可能である(すべてが対象であり、クラス自体が目標です)

典型的なオブジェクトのインスタンス化

class Foo:
    f = '类的静态变量'
    def __init__(self,name,age):
        self.name=name
        self.age=age

    def say_hi(self):
        print('hi,%s'%self.name)

obj=Foo('egon',73)

#检测是否含有某属性
print(hasattr(obj,'name'))
print(hasattr(obj,'say_hi'))

#获取属性
n=getattr(obj,'name')
print(n)
func=getattr(obj,'say_hi')
func()

print(getattr(obj,'aaaaaaaa','不存在啊')) #报错

#设置属性
setattr(obj,'sb',True)
setattr(obj,'show_name',lambda self:self.name+'sb')
print(obj.__dict__)
print(obj.show_name(obj))

#删除属性
delattr(obj,'age')
delattr(obj,'show_name')
delattr(obj,'show_name111')#不存在,则报错

print(obj.__dict__)

オブジェクトのリフレクション

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')

クラスのリフレクション

import sys

def s1():
    print 's1'

def s2():
    print 's2'

this_module = sys.modules[__name__]

hasattr(this_module, 's1')
getattr(this_module, 's2')

反射し、現在のモジュール

#一个模块中的代码
def test():
    print('from the test')
"""
程序目录:
    module_test.py
    index.py
 
当前文件:
    index.py
"""
# 另一个模块中的代码
import module_test as obj

#obj.test()

print(hasattr(obj,'test'))

getattr(obj,'test')()

他のモジュールの反射光

アプリケーションのリフレクション:

反射の4つの機能をご覧ください。その後の使用は、それが何であるかを最終的に反射?そのシナリオは、それがどのようなものですか?

今、聞かせてのは、ブラウザを開き、ウェブサイトを訪問、ログオンするためのログイン画面にジャンプする]をクリックし、インターフェイスを登録する登録ジャンプをクリックして、というように、実際にあなたが実際にリンクのいずれか、それぞれをクリックしてくださいリンクに対処するための関数やメソッドを持つことになります。

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()

反射を学ぶことがなかった以前のソリューション

class User:
    def login(self):
        print('欢迎来到登录页面')
    
    def register(self):
        print('欢迎来到注册页面')
    
    def save(self):
        print('欢迎来到存储页面')

user = User()
while 1:
    choose = input('>>>').strip()
    if hasattr(user,choose):
        func = getattr(user,choose)
        func()
    else:
        print('输入错误。。。。')

反射ソリューションを学んだ後

どのようにシンプルな一目。

II。方法対機能

ここで学んだ、私は最終的にあなたが質問されている可能性がありお答えすることができました。、我々は(LEN呼び出す前の研究であること)と述べている(舌の滑りをするときの方法と呼ばれる)関数は最後に、それは何と呼ばれていることを、ストリップSTRの方法としてあるのですか?関数とメソッドの違いと類似点は何ですか?私は公式の説明にここにいます。

2.1関数(メソッド)の名前を印刷することにより決定されます

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>>
View Code

モジュールの種類によって検証2.2

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

2.3静的メソッドの関数であります

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

2.4関数とメソッドの違い

だから、上記の関数やメソッドのほかに異なっている、我々は以下の点差を要約しています。

(1)関数は、明示的にデータを渡しています。我々はいくつかのデータを渡すためにlenは()関数として示したい場合は処理されます。

(2)関数はオブジェクトとは何の関係もありません。

データ(3)メソッドが暗黙的に送信されます。

(4)内部のクラスのデータを操作する方法。

(5)メソッドは、オブジェクトに関連付けられています。我々は、コールはないので、我々は文字列sは、その後で呼ばれる)(s.strip持っているようなストリップに()メソッドstrのオブジェクト、です。はい、ストリップ()メソッドは、オブジェクトSTRに属します。

おそらく、関数やメソッドを呼び出すときに、私たちは日常口語緩んになりますが、私たちの心は両者の違いを知っています。

そのようなJavaメソッドなど他の言語でのみ、Cのみの機能は、C ++には、それがクラスかどうかに依存します。

III。ビス方法

定義:ダブルダウンは特別な方法であり、彼の方法は、メソッド名が提供する特別な意味インタプリタであるプラスダブル下線付きの名前にアンダー冷却__ __方法、方法のpython-ソースプログラマーをダブルダウンすることで、我々開発中のメソッドをダブルダウンしようとするが、さらに研究方法は、ソースコードを読むために、私たちに多くの有益を倍にしないでください。

コール:墓は、無意識のうちに例えば、2アンダーの方法を契機に、同じ臓器がトリガーのような異なる方法の下で、二重に、異なるトリガモードを持っています。init

1.3 __len

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))

3.02 __hash

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.03 STR

クラスは__str__メソッドが定義されている場合、印刷対象は、この方法は、デフォルトの出力値を返す場合。

class A:
    def __init__(self):
        pass
    def __str__(self):
        return '太白'
a = A()
print(a)
print('%s' % a)

3.04のrepr

クラスは__repr__方法が定義されている場合、その後のrepr(オブジェクト)には、この方法は、デフォルトの出力値を返します。

class A:
    def __init__(self):
        pass
    def __repr__(self):
        return '太白'
a = A()
print(repr(a))
print('%r'%a)

3.05コール

オブジェクトの背後にあるブラケットには、実行をトリガ。

注:クラス名=オブジェクト()呼び出しに対するオブジェクトトリガーの方法によってブラケットを行う、即ち:コンストラクタが__new__は、オブジェクトを作成するためにトリガされる、つまりによって実行される(オブジェクト()またはクラス() )

class Foo:

    def __init__(self):
        pass    
    def __call__(self, *args, **kwargs):
        print('__call__')

obj = Foo() # 执行 __init__
obj()       # 执行 __call__

3.06 __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)

の3.07

オブジェクトがメモリにリリースされたデストラクタは、自動的に実行をトリガ。

注:このメソッドは、この作業を実行するPythonインタプリタにあるので、Pythonは高レベルの言語であるので、心配しないで使用プログラマが割り当て、空きメモリ、一般的に定義する必要はありませんので、デストラクタがある呼び出しトリガ自動的インタプリタにより時間ガベージコレクタで行います。

3.08__new

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 ++)で、他のクラスのインスタンスオブジェクトを削除することができ、これは参照の懸濁液につながります

3.09 __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__)

3.10関連するコンテキストマネージャ

enter __exit

# 如果想要对一个类的对象进行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)
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())

おすすめ

転載: www.cnblogs.com/xxpythonxx/p/12623312.html