Python實現IOC控制反轉

2021-08-13 19:29:44 字數 4506 閱讀 2818

用乙個字典儲存beanname和資源

初始化時先將beanname和資源註冊到字典中

然後用乙個dscriptor類根據beanname動態請求資源,從而實現控制反轉

# -*- coding:utf-8 -*-

import os

class

beanfactory:

""" python版控制反轉

context: 儲存bean的名字和對應的類或者值的字典

allowrepalce: 是否允許替換已經注入的bean

"""def__init__

(self,allowreplace=false):

"""建構函式

allowreplace:是否允許替換已經注入的bean

"""self.context = {}

self.allowreplace = allowreplace

defsetbean

(self,beanname,resource,*args,**kwargs):

ifnot self.allowreplace:

assert

not beanname in self.context,"該beanfactory不允許重複注入%r,請修改beanname" % beanname

defcall

():"""定義乙個函式閉包,如果注入的resource是可呼叫型別,就將*args和**kwargs傳入並呼叫該函式,然後將返回值返回

如果是乙個不可呼叫物件,就直接返回

"""if callable(resource):

return resource(*args,**kwargs)

else:

return resource

#將call閉包與beanname建立對映

self.context[beanname]=call

def__getitem__

(self,beanname):

"""過載__getitem__方法,使得beanfactory支援使用獲取beanname對應的註冊的資源

"""try:

# 從context字典中取出beanname對應的資源

resource = self.context[beanname]

except keyerror:

raise keyerror("%r 未註冊" % beanname)

# 返回閉包函式呼叫後的結果

return resource()

defnoassertion

(obj):

return

true

defisinstanceof

(*classes):

deftest

(obj):

return isinstance(obj, classes)

return test

defhasattributes

(*attributes):

deftest

(obj):

for each in attributes:

ifnot hasattr(obj, each): return

false

return

true

return test

defhasmethods

(*methods):

deftest

(obj):

for each in methods:

try:

attr = getattr(obj, each)

except attributeerror:

return

false

ifnot callable(attr): return

false

return

true

return test##

#descriptor就是一類實現了__get__(), __set__(), __delete__()方法的物件

#若乙個類的成員是descriptor,在訪問它的值時是通過__get__()函式訪問的

#用這個特性實現在訪問乙個類的成員時自動到beanfactory中請求對應的資源

class

requiredresource

(object):

def__init__

(self, beanname, assertion=noassertion):

self.beanname = beanname

self.assertion = assertion

def__get__

(self, obj, t):

#每次訪問descriptor時都會呼叫__get__方法

return self.result # <-- .操作符會自動呼叫__getattr__

def__getattr__

(self, name):

assert name == 'result', "unexpected attribute request other then 'result'"

self.result = self.request()

return self.result

defrequest

(self):

assert self.assertion(obj), \

"the value %r of %r does not match the specified criteria" \

% (obj, self.feature)

return obj

class

component

(object):

"symbolic base class for components"

class

bar(component):

# hasmethods是乙個閉包函式,傳入requiredresource後用於檢查'console'

# 對應的註冊的那個feature是否有'writeline'方法

# isinstanceof(str) 是乙個閉包,傳入requiredresource後會被呼叫,用於

# isinstanceof(str) 是乙個閉包,傳入requiredresource後會被呼叫,用於

# 檢查'currentuser'對應的資源是否是乙個字串

# requiredfeatuire是desciptor,每次訪問descriptor(即實現了__get__的類),都會先經過__get__函式。

con = requiredresource('console', hasmethods('writeline'))

user = requiredresource('currentuser', isinstanceof(str))

flist = requiredresource('show_dir',isinstanceof(list))

def__init__

(self):

self.x = 0

defprintyourself

(self):

self.con.writeline('-- bar instance --')

self.con.writeline('title: %s' % self.title)

self.con.writeline('user: %s' % self.user)

self.con.writeline('x: %d' % self.x)

for f in self.flist:

self.con.writeline(f)

class

betterconsole

(component):

def__init__

(self, prefix=''):

self.prefix = prefix

defwriteline

(self, s):

lines = s.split('\n')

for line in lines:

if line:

print(self.prefix, line)

else:

print

defgetcurrentuser

():return os.getenv('username') or

'some user'

# username is platform-specific

defshowdir

():return os.listdir()

if __name__ == '__main__':

print('\n*** ioc demo ***')

#provide(feature,provider,*args,**kwargs) feature是要生成的物件的父類型別 provider是要注入的子類或者值

bar = bar()

bar.printyourself()

IoC控制反轉

首先假設有乙個需求,類business需要呼叫類dependency的方法f 1 按照日常的做法,得到下面的 類dependency public class dependency 類business public class business public void dosomething 2 對...

IOC 控制反轉

ioc是物件導向程式設計中的一種設計原則,可以借助 第三方 來減低計算機 之間的 耦合度 其中最常見的方式叫做依賴注入 dependency injection,簡稱di 還有一種方式叫 依賴查詢 dependency lookup 通過控制反轉,物件在被建立的時候,由乙個調控系統內所有物件的外界實...

IOC 控制反轉

想說說ioc inversion of control,控制反轉 這是spring的核心,貫穿始終。所謂ioc,對於spring框架來說,就是由spring來負責控制物件的生命週期和物件間的關係。這是什麼意思呢,舉個簡單的例子,我們是如何找女朋友的?常見的情況是,我們到處去看 有長得漂亮身材又好的m...