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

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

36插件化開發(fā)_slots_radd

?

創(chuàng)新互聯(lián)專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、濉溪網(wǎng)絡(luò)推廣、小程序開發(fā)、濉溪網(wǎng)絡(luò)營(yíng)銷、濉溪企業(yè)策劃、濉溪品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營(yíng)等,從售前售中售后,我們都將竭誠(chéng)為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供濉溪建站搭建服務(wù),24小時(shí)服務(wù)熱線:18982081108,官方網(wǎng)址:www.cdcxhl.com

?

目錄

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

動(dòng)態(tài)導(dǎo)入:...1

插件化編程技術(shù):...3

__slots__.4

未實(shí)現(xiàn)和未實(shí)現(xiàn)異常:...6

運(yùn)算符重載中的反向方法:...6

?

?

?

插件化開發(fā)

?

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

?

動(dòng)態(tài)導(dǎo)入:

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

?

1、__import__(),內(nèi)建函數(shù);

2、importlib.import_module(),import_module(name, package=None),支持絕對(duì)導(dǎo)入和相對(duì)導(dǎo)入,相對(duì)導(dǎo)入則必須要設(shè)置package;

?

import語(yǔ)句本質(zhì)上就是調(diào)用__import__()這個(gè)函數(shù),但不建議直接使用__import__(),建議使用importlib.import_module();

?

?

1、內(nèi)建函數(shù)__import__();

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

name,模塊名;

?

sys = __import__('sys')?? #等價(jià)于import sys,運(yùn)行時(shí)加載

?

例:

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')?? #加載后會(huì)放到sys.modules里,搜索順序是在sys.path中找

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

???????? getattr(mod,'A')().show()?? #getattr(object, name[, default]) -> value,等價(jià)于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

?

?

插件化編程技術(shù):

依賴的技術(shù):

reflection,反射,運(yùn)行時(shí)獲取類型的信息,可動(dòng)態(tài)維護(hù)類型數(shù)據(jù);

動(dòng)態(tài)import,推薦使用importlib.import_module(),實(shí)現(xiàn)動(dòng)態(tài)import模塊的能力;

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

?

加載的時(shí)機(jī):

程序啟動(dòng)時(shí)?還是程序運(yùn)行中?

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

程序運(yùn)行時(shí),程序運(yùn)行過程中,接受用戶指令或請(qǐng)求,啟動(dòng)相應(yīng)的插件;

兩種方式各有利弊,如果插件過多,會(huì)導(dǎo)致程序啟動(dòng)很慢,如果用戶需要時(shí)加載,若插件太多或依賴多,插件也會(huì)啟動(dòng)慢;

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

?

應(yīng)用:

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

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

?

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

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

插件是把模塊加載到系統(tǒng)中,運(yùn)行它,增強(qiáng)當(dāng)前系統(tǒng)功能,或提供系統(tǒng)不具備的功能,往往插件技術(shù)應(yīng)用在框架設(shè)計(jì)中,系統(tǒng)本身設(shè)計(jì)簡(jiǎn)單化、輕量級(jí)、實(shí)現(xiàn)基本功能后,其它功能通過插件加入進(jìn)來,方便擴(kuò)展;

?

銷售:

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

另一些軟件把相應(yīng)功能的菜單隱藏了,通過序列號(hào)可打開隱藏的這些功能;

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

?

?

?

__slots__

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

一般來說,一個(gè)對(duì)象,屬性都存儲(chǔ)在字典中便于查詢,問題不大;但如果數(shù)百萬(wàn)個(gè)對(duì)象,字典就有點(diǎn)大了;這個(gè)時(shí)候,能否把屬性字典__dict__給省了;py提供了__slots__;

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

?

實(shí)例用;標(biāo)準(zhǔn)庫(kù)中用得多;

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

類屬性不影響;

?

應(yīng)用場(chǎng)景:

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

當(dāng)要使用數(shù)百萬(wàn)個(gè)對(duì)象,且內(nèi)存容量較為緊張的場(chǎng)景;

?

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

?

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

?

例:

class A:

??? x = 123

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

??? 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,實(shí)例屬性被限制,實(shí)例的__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__)?? #繼承類的實(shí)例不受__slots__影響,__slots__管不到自己的子類,控制不了子類;__slots__不影響子類實(shí)例,不會(huì)繼承下去,除非子類里面自己也定義了__slots__;__slots__一般在子類上用,而且是最下面的子類,父類功能不全

輸出:

{'b1': 500}

?

?

?

未實(shí)現(xiàn)和未實(shí)現(xiàn)異常:

?

print(type(NotImplemented))

print(type(NotImplementedError))

輸出:

?? #是個(gè)值,單值,是NotImplementedType類的實(shí)例

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

?

例:

class A:

??? def showme(self):

??????? raise NotImplementedError

?

print(A().showme())

?

?

?

運(yùn)算符重載中的反向方法:

?

例:

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)沒有實(shí)現(xiàn)__add__(),int中有所有的方法

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

輸出:

__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等價(jià)于b.__add__(a),但類B沒有實(shí)現(xiàn)__add__(),就去找a的__radd__()方法

輸出:

__add__ <__main__.Add object at 0x7f02a03f7160>

10

__radd__ <__main__.Add object at 0x7f02a03f7160>

__add__ <__main__.Add object at 0x7f02a03f7160>

10

?

?

?

?


新聞標(biāo)題:36插件化開發(fā)_slots_radd
當(dāng)前路徑:http://weahome.cn/article/gpcehh.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部