欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python實現(xiàn)動態(tài)實例化的示例代碼

 更新時間:2025年06月19日 08:17:43   作者:花酒鋤作田  
這篇文章主要為大家詳細介紹了使用Python實現(xiàn)動態(tài)實例化的相關知識,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下

前言

最近在查一個服務的問題時,看到有一段代碼if .. elif ... 寫了近百行,類似

if command == "xxx":
	obj = CommandX()
	obj.run()
	# ...
elif command == "yyy":
	obj = CommandY()
	obj.run()
    # ...
elif command == "zzz":
	obj = CommandZ()
	obj.run()
    # ...

# ...

翻了下git記錄,最開始其實只有兩三個條件判斷,后來command越加越多,就這么延續(xù)下來了。

代碼邏輯其實沒什么問題,也很簡單明了,就是看起來有點丑,而且我還開了比較高的桌面縮放,導致一屏幕幾乎都是這段if ... elif

看來看去越發(fā)覺得丑,先寫個demo看看能不能跑通代碼。

方式1:字典映射

如果需要判斷的條件比較少,用字典做映射還是挺方便的,但如果條件多,看起來還是挺丑的。

from abc import ABC, abstractmethod

class AbstractCommand(ABC):
    @abstractmethod
    def run(self):
        pass

class CommandA(AbstractCommand):
    def run(self):
        return "this is command A"
    
class CommandB(AbstractCommand):
    def run(self):
        return "this is command B"
    
class CommandC(AbstractCommand):
    def run(self):
        return "this is command C"
    
class CommandFactory:
    @staticmethod
    def create_command(command_type: str) -> AbstractCommand:
        command_mapping = {
            "cmda": CommandA,
            "cmdb": CommandB,
            "cmdc": CommandC
        }
        cls = command_mapping.get(command_type.lower())
        if not cls:
            raise ValueError(f"Unknown command type: {command_type}")
        return cls()
    
if __name__ == "__main__":
    cmd = CommandFactory.create_command("cmda")
    assert cmd.run() == "this is command A"

    cmd = CommandFactory.create_command("cmdb")
    assert cmd.run() == "this is command B"

    cmd = CommandFactory.create_command("cmdc")
    assert cmd.run() == "this is command CD"  # should be exception

    cmd = CommandFactory.create_command("cmdd")  # should be exception
    assert cmd.run() == "this is command D"

方式2: __init_subclass__

《流暢的Python(第2版)》的最后一章提到了這個__init__subclass__,根據(jù)python官方文檔:

當所在類派生子類時此方法就會被調用。cls 將指向新的子類。如果定義為一個普通實例方法,此方法將被隱式地轉換為類方法。傳給一個新類的關鍵字參數(shù)會被傳給上級類的 __init_subclass__。 為了與其他使用 __init_subclass__ 的類兼容,應當去掉需要的關鍵字參數(shù)再將其他參數(shù)傳給基類。

借助這個機制,可以在實現(xiàn)抽象基類時自動注冊子類,避免手動維護注冊表。

from abc import ABCMeta, abstractmethod
from threading import Lock
from collections import UserDict

class ThreadSafeDict(UserDict):
    """線程安全的字典"""
    def __init__(self):
        super().__init__()
        self._lock = Lock()
    
    def __setitem__(self, key, item):
        with self._lock:
            super().__setitem__(key, item)

class Command(metaclass=ABCMeta):
    registry = ThreadSafeDict()

    def __init__(self):
        pass

    @abstractmethod
    def run(self):
        pass

    def __init_subclass__(cls, **kwargs):
        super().__init_subclass__(**kwargs)
        cls.registry[cls.__name__.lower()] = cls  # 自動注冊子類

# 子類定義即自動注冊
class CommandA(Command):
    def run(self):
        return "this is command a!"

class CommandB(Command):
    def run(self):
        return "this is command b!"

class CommandC(Command):
    def run(self):
        return "this is command b!"
    
def create_command(command_type: str) -> Command:
    """工廠函數(shù)"""
    cls = Command.registry.get(command_type.lower())
    if not cls:
        raise ValueError(f"Unknown command type: {command_type}")
    return cls()
    
if __name__ == "__main__":
    cmd = create_command("CommandA")
    assert cmd.run() == "this is command a!"
    cmd = create_command("CommandB")
    assert cmd.run() == "this is command b!"
    cmd = create_command("CommandC")
    assert cmd.run() == "this is command cc!"  # should be exception
    cmd = create_command("CommandD")
    assert cmd.run() == "this is command b!"  # should be exception

乍一看還是挺不錯的,但是也有個缺點,那就是如果各個類分散在不同模塊中,那么工廠函數(shù)所在的模塊就要寫一堆from xxx import ...

如果module和類命名比較規(guī)范,也可以這么動態(tài)加載類

import importlib

def create_class(module_name, class_name):
    module = importlib.import_module(module_name)
    cls = getattr(module, class_name)
    return cls()

補充

自動注冊類看起來炫,但是對代碼閱讀來說不是很直觀。易讀還是美觀?這是一個問題。

到此這篇關于Python實現(xiàn)動態(tài)實例化的示例代碼的文章就介紹到這了,更多相關Python動態(tài)實例化內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Python中的異常處理簡明介紹

    Python中的異常處理簡明介紹

    這篇文章主要介紹了Python中的異常處理簡明介紹,本文講解了try-except檢測異常、上下文管理器(with…as…語句)、raise引發(fā)異常、斷言等內容,需要的朋友可以參考下
    2015-04-04
  • python使用mitmproxy抓取瀏覽器請求的方法

    python使用mitmproxy抓取瀏覽器請求的方法

    今天小編就為大家分享一篇python使用mitmproxy抓取瀏覽器請求的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-07-07
  • Django 實現(xiàn)admin后臺顯示圖片縮略圖的例子

    Django 實現(xiàn)admin后臺顯示圖片縮略圖的例子

    今天小編就為大家分享一篇Django 實現(xiàn)admin后臺顯示圖片縮略圖的例子,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-07-07
  • Python之os模塊案例詳解

    Python之os模塊案例詳解

    這篇文章主要介紹了Python之os模塊案例詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下
    2021-09-09
  • python多進程并發(fā)demo實例解析

    python多進程并發(fā)demo實例解析

    這篇文章主要介紹了python多進程并發(fā)demo實例解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-12-12
  • Scrapy將數(shù)據(jù)保存到Excel和MySQL中的方法實現(xiàn)

    Scrapy將數(shù)據(jù)保存到Excel和MySQL中的方法實現(xiàn)

    本文主要介紹了Scrapy將數(shù)據(jù)保存到Excel和MySQL中的方法實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-02-02
  • python日期時間轉為字符串或者格式化輸出的實例

    python日期時間轉為字符串或者格式化輸出的實例

    今天小編就為大家分享一篇python日期時間轉為字符串或者格式化輸出的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05
  • Python爬蟲分析微博熱搜關鍵詞的實現(xiàn)代碼

    Python爬蟲分析微博熱搜關鍵詞的實現(xiàn)代碼

    這篇文章主要介紹了Python爬蟲分析微博熱搜關鍵詞的實現(xiàn)代碼,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-02-02
  • python里運用私有屬性和方法總結

    python里運用私有屬性和方法總結

    在本文里我們給大家分享了關于python里運用私有屬性和方法總結以及相關知識點內容,有興趣的朋友們跟著參考學習下。
    2019-07-07
  • python實現(xiàn)掃描日志關鍵字的示例

    python實現(xiàn)掃描日志關鍵字的示例

    下面小編就為大家分享一篇python實現(xiàn)掃描日志關鍵字的示例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-04-04

最新評論