1. 程式人生 > >python 64式: 第12式、用stevedore寫python外掛

python 64式: 第12式、用stevedore寫python外掛

先建立專案目錄:  mystevedore

然後新建一個目錄: people,該目錄

下面分別包含:

__init__.py

chinese.py
english.py
pluginBase.py

檔案

__init__.py 檔案內容為空

pluginBase.py檔案內容如下

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import abc
import six

@six.add_metaclass(abc.ABCMeta)
class PeopleBase(object):
    def __init__(self):
        pass

    @abc.abstractmethod
    def say(self):

chinese.py檔案內容如下

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from pluginBase import PeopleBase

class Chinese(PeopleBase):
    def say(self):
        return "ni hao"

english.py檔案內容如下

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from pluginBase import PeopleBase

class Chinese(PeopleBase):
    def say(self):
        return "hello"

專案目錄:  mystevedore專案目錄下新建一個檔案setup.py,檔案內容如下

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from setuptools import find_packages
from setuptools import setup

setup(
    name='mm_stevedore_test',
    version='1.0',
    packages=find_packages(),
    entry_points={
        'people.say': [
            'chinese = people.chinese:Chinese',
            'english = people.english:English'
        ],
    }
)

然後執行如下命令安裝該上述編寫的外掛

python setup.py install

最後編寫呼叫外掛的檔案 main.py,內容如下

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from stevedore import driver

'''
關鍵:
1 stevedore
含義:動態載入程式碼的庫,允許在執行時通過發現和載入擴充套件(外掛)應用。
     使用setuptools的entry points來定義並載入外掛。
     entry point引用的是定義在模組中的物件(類,物件,例項),只要在import模組時能夠被建立
2 entry points
  entry points:本質上是提供給外界呼叫的程式或者類
  entry points可以獨立註冊,需要開發者和使用者在名稱空間和外掛名稱上一致
3 外掛
外掛種類:
1) stevedore.driver.DriverManager :一個名字對應一個entry point。根據外掛名稱空間和名字,定位到單獨外掛
stevedore.driver.DriverManager(namespace, name, invoke_on_load, invoke_args=(), invoke_kwds={})
namespace: 名稱空間
name: 外掛名稱
invoke_on_load:如果為True,表示會例項化該外掛的類
invoke_args:呼叫外掛物件時傳入的位置引數
invoke_kwds:傳入的字典引數

2) stevedore.hook.HookManager :一個名字對應多個entry point,根據給定名稱空間和名字,載入名字對應的多個外掛
3) stevedore.extension.ExtensionManager: 多個名字,多個entry point。給定名稱空間,載入該名稱空間所有外掛

4 外掛格式
名稱空間 = 
  外掛名稱=模組:可匯入物件

外掛例子:
ceilometer.compute.virt = 
    libvirt = ceilometer.compute.virt.libvirt.inspector:LibvirtInspector
    hyperv = ceilometer.compute.virt.hyperv.inspector:HyperVInspector
解釋:
ceilometer.compute.virt 是名稱空間
libvirt 是外掛名稱
ceilometer.compute.virt.libvirt.inspector 是模組
LibvirtInspector 是可匯入物件,實際是一個類

5 使用外掛步驟:
1) 使用abc模組建立抽象基類定義外掛API行為
2) 通過繼承基類並實現必要的方法來建立外掛
3) 為每個api定義一個名稱空間,可將應用,API名字結合起來
  例如: people.say
4) setup.py中註冊:
例如:
from setuptools import find_packages,setup
setup(
    name='mm_stevedore_test',
    version='1.0',
    packages=find_packages(),
    entry_points={
        'people.say': [
            'chinese = people.chinese:Chinese',
            'english = people.english:English'
        ],
    }
)
5) 安裝外掛所在模組,即在外掛程式碼下執行如下命令:
python setup.py install
6)呼叫外掛:
編寫一個.py檔案,該.py檔案可以不和外掛模組程式碼在同一目錄,呼叫形式類似如下
mgr = stevedore.driver.DriverManager(
    namespace='people.say',
    name='chinese',
    invoke_on_load=True,
    invoke_args=(),
)
result = mgr.driver.say()

總結:
stevedore庫可以用於註冊外掛,之所以使用外掛是因為可以使自己的程式可以呼叫別人編寫的程式碼,進行解藕。外掛格式是:
名稱空間= 
  外掛名稱=模組:可匯入物件

參考:
[1] http://blog.csdn.net/gqtcgq/article/details/49620279
[2] https://blog.csdn.net/happyanger6/article/details/54798870
'''

def process():
    mgr = driver.DriverManager(
        namespace='people.say',
        name='chinese',
        invoke_on_load=True,
        invoke_args=(),
    )
    # 注意: 這裡呼叫的是 mgr.driver.say() 而不是 mgr.say(),不要漏了driver
    result = mgr.driver.say()
    print result

if __name__ == "__main__":
    process()