真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯網站制作重慶分公司

36插件化開發(fā)_slots_radd-創(chuàng)新互聯

目錄

創(chuàng)新互聯致力于互聯網網站建設與網站營銷,提供網站建設、成都網站設計、網站開發(fā)、seo優(yōu)化、網站排名、互聯網營銷、重慶小程序開發(fā)公司、公眾號商城、等建站開發(fā),創(chuàng)新互聯網站建設策劃專家,為不同類型的客戶提供良好的互聯網應用定制解決方案,幫助客戶在新的全球化互聯網環(huán)境中保持優(yōu)勢。

插件化開發(fā)...1

動態(tài)導入:...1

插件化編程技術:...3

__slots__.4

未實現和未實現異常:...6

運算符重載中的反向方法:...6

插件化開發(fā)

例:notepad++中插件;firefox、chrome插件;eclipse;

動態(tài)導入:

運行時,根據用戶(程序員)需求(如提供字符串),找到模塊的資源動態(tài)加載起來;

1、__import__(),內建函數;

2、importlib.import_module(),import_module(name, package=None),支持絕對導入和相對導入,相對導入則必須要設置package;

import語句本質上就是調用__import__()這個函數,但不建議直接使用__import__(),建議使用importlib.import_module();

1、內建函數__import__();

__import __(name,globals=None,locals=None,fromlist=(),level=0)

name,模塊名;

sys = __import__('sys')?? #等價于import sys,運行時加載

例:

example_module_test1.py

class A:

def show(self):

print(type(self).__name__)

print(type(self.__module__))

example_plugins.py

if __name__ == '__main__':

mod = __import__('example_module_test1')?? #同import example_module_test1

getattr(mod,'A')().show()

輸出:

A

例:

def plugin_load():

mod = __import__('example_module_test1')?? #加載后會放到sys.modules里,搜索順序是在sys.path中找

# print(type(mod))??? #

getattr(mod,'A')().show()?? #getattr(object, name[, default]) -> value,等價于mod.A().show()

# mod.A().show()

if __name__ == '__main__':

plugin_load()

輸出:

A

例:

def plugin_load(plugin_name:str,sep=':'):

m,_,c = plugin_name.partition(sep)

mod = __import__(m)

cls = getattr(mod,c)

return cls()

if __name__ == '__main__':

# plugin_load()

plugin_load('example_module_test1:A').show()

2、importlib.import_module():

例:

import importlib

def plugin_load(plugin_name:str,sep=':'):

# m,_,c = plugin_name.partition(sep)

m,c = plugin_name.split(sep)

mod = importlib.import_module(m)?? #推薦用此種,不要用__import__()

cls = getattr(mod,c)

return cls()

if __name__ == '__main__':

# plugin_load()

plugin_load('example_module_test1:A').show()

輸出:

A

插件化編程技術:

依賴的技術:

reflection,反射,運行時獲取類型的信息,可動態(tài)維護類型數據;

動態(tài)import,推薦使用importlib.import_module(),實現動態(tài)import模塊的能力;

多線程,可開啟一個線程,等待用戶輸入,從而加載指定名稱的模塊;

加載的時機:

程序啟動時?還是程序運行中?

程序啟動時,像pycharm這樣的工具,需要很多組件,這些組件也可能是插件,啟動的時候掃描固定的目錄,加載插件;

程序運行時,程序運行過程中,接受用戶指令或請求,啟動相應的插件;

兩種方式各有利弊,如果插件過多,會導致程序啟動很慢,如果用戶需要時加載,若插件太多或依賴多,插件也會啟動慢;

所以先加載必須的、常用的插件,其它插件使用時,發(fā)現需要,動態(tài)載入;

應用:

軟件的設計不可能盡善盡美,或在某些功能上,不可能做的專業(yè),需要專業(yè)的客戶自己增強;

如notepadd++,它只需要做好一個文本編輯器就可以了,其它增強功能都通過插件的方式提供,如拼寫檢查、HTML預覽、正則插件等;要定義規(guī)范、定義插件從哪里加載、如何加載、必須實現的功能等;

接口和插件區(qū)別:

接口往往是暴露出來的功能,接口指的是操作(方法|函數),如模塊提供了函數和方法,加載模塊后調用這些函數完成功能;接口也是一種規(guī)范,它約定了必須實現的功能(必須提供某名稱的函數),但不關心怎么實現這個功能;api,application program interface;url指向的是后臺應用中某個類的方法;

插件是把模塊加載到系統(tǒng)中,運行它,增強當前系統(tǒng)功能,或提供系統(tǒng)不具備的功能,往往插件技術應用在框架設計中,系統(tǒng)本身設計簡單化、輕量級、實現基本功能后,其它功能通過插件加入進來,方便擴展;

銷售:

插件化需求,旗艦版、家庭版;

另一些軟件把相應功能的菜單隱藏了,通過序列號可打開隱藏的這些功能;

軟件達到一定規(guī)模,必須做成框架,越需要插件化思想;常用的先加載,不常用的懶加載;

__slots__

都是字典惹的禍,字典為了提升查詢效率,必須用空間換時間(為了hash得占用一定的空間);

一般來說,一個對象,屬性都存儲在字典中便于查詢,問題不大;但如果數百萬個對象,字典就有點大了;這個時候,能否把屬性字典__dict__給省了;py提供了__slots__;

可理解為就給這幾個槽位放東西,用__slots__規(guī)定有什么樣的屬性;

實例用;標準庫中用得多;

限制實例暴露出的屬性供別人使用;

類屬性不影響;

應用場景:

未來可能產生大量實例,這些實例中有不需要的屬性,用__slots__暴露出可用的屬性,且用元組形式列出(是可迭代對象均可,一個屬性時字符串也可);

當要使用數百萬個對象,且內存容量較為緊張的場景;

__slots__ = 'p1'或__slots__ = 'p1','p2'均可,建議用元組形式__slots__ = ('p1','p2'),__slots__告訴解釋器,實例的屬性都叫什么,一般來說既然要節(jié)約內存,最好還是用元組,一旦類提供了__slots__就阻止實例產生__dict__來保存實例的屬性;

繼承類的實例不受__slots__影響,__slots__管不到自己的子類,控制不了子類;__slots__不影響子類實例,不會繼承下去,除非子類里面自己也定義了__slots__;__slots__一般在子類上用,而且是最下面的子類,父類功能不全;

例:

class A:

x = 123

__slots__ = ('p1','p2')?? #__slots__ = 'p1'或__slots__ = 'p1','p2'均可,建議用元組形式__slots__ = ('p1','p2'),__slots__告訴解釋器,實例的屬性都叫什么,一般來說既然要節(jié)約內存,最好還是用元組,一旦類提供了__slots__就阻止實例產生__dict__來保存實例的屬性

def __init__(self):

self.p1 = 1

self.p2 = 2

def showme(self):

print('I am A.{}'.format(self.p1))

print(A.__dict__)

# print(A().__dict__)?? #X,實例屬性被限制,實例的__dict__消失了

print(A().__slots__)

a = A()

a.p2 = 200

# a.x = 300?? # AttributeError: 'A' object attribute 'x' is read-only

A.x = 500

輸出:

{'__module__': '__main__', 'x': 123, '__slots__': ('p1', 'p2'), '__init__': , 'showme': , 'p1': , 'p2': , '__doc__': None}

('p1', 'p2')

1 200

例:

class A:

x = 123

__slots__ = ('p1','p2')

def __init__(self):

self.p1 = 1

self.p2 = 2

def showme(self):

print('I am A.{}'.format(self.p1))

class B(A):

def __init__(self):

self.b1 = 500

print(B().__dict__)?? #繼承類的實例不受__slots__影響,__slots__管不到自己的子類,控制不了子類;__slots__不影響子類實例,不會繼承下去,除非子類里面自己也定義了__slots__;__slots__一般在子類上用,而且是最下面的子類,父類功能不全

輸出:

{'b1': 500}

未實現和未實現異常:

print(type(NotImplemented))

print(type(NotImplementedError))

輸出:

?? #是個值,單值,是NotImplementedType類的實例

?? #是類型,是異常,返回type,父類RuntimeError-->父類Exception

例:

class A:

def showme(self):

raise NotImplementedError

print(A().showme())

運算符重載中的反向方法:

例:

class Add:

def __init__(self,x:int):

self.x = x

def __add__(self, other):

print('__add__',self)

# return self.x + other.x

return self.x + other

# def __add__(self, other):

#???? print('__add__',self)

#???? try:

#???????? res = self.x + other.x

#???? except:

#???????? try:

#???????????? o = int(other)

#???????? except:

#???????????? o = 0

#???????? res = self.x + o

#???? return res

# def __add__(self, other):

#???? print('__add__',self)

#???? try:

#???????? o = int(other.x)

#???? except:

#???????? o = 0

#???? return self.x + 0

def __iadd__(self, other):

print('__iadd__',self)

return self.x + other.x

def __radd__(self, other):

print('__radd__',self)

# return self.x + other.x

return self + other

a = Add(4)

b = Add('abc')

# print(a+b)

# print(a+=b)

# print(b+a)

# print(a+1)?? #不是1(int)沒有實現__add__(),int中有所有的方法

print(1+a)?? #1+a等價于1.__add__(a),而Int類實現了__add__(),不過這個方法對于這種加法的返回值是NotImplemented,解釋器發(fā)現是這個值,就會發(fā)起對第二操作對象的__radd__()調用

輸出:

__radd__ <__main__.Add object at 0x7f42d83acfd0>

__add__ <__main__.Add object at 0x7f42d83acfd0>

5

例:

class Add:

def __init__(self,x:int):

self.x = x

def __add__(self, other):

print('__add__',self)

return self.x + other.x

def __iadd__(self, other):

print('__iadd__',self)

return self.x + other.x

def __radd__(self, other):

print('__radd__',self)

# return self.x + other.x

return self + other

class B:

def __init__(self,x):

self.x = x

a = Add(4)

b = B(6)

print(a+b)

print(b+a)?? #b+a等價于b.__add__(a),但類B沒有實現__add__(),就去找a的__radd__()方法

輸出:

__add__ <__main__.Add object at 0x7f02a03f7160>

10

__radd__ <__main__.Add object at 0x7f02a03f7160>

__add__ <__main__.Add object at 0x7f02a03f7160>

10

另外有需要云服務器可以了解下創(chuàng)新互聯cdcxhl.cn,海內外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。


文章題目:36插件化開發(fā)_slots_radd-創(chuàng)新互聯
鏈接URL:http://weahome.cn/article/isici.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部