最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python實(shí)現(xiàn)動(dòng)態(tài)實(shí)例化的示例代碼

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

前言

最近在查一個(gè)服務(wù)的問(wèn)題時(shí),看到有一段代碼if .. elif ... 寫(xiě)了近百行,類(lèi)似

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

# ...

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

代碼邏輯其實(shí)沒(méi)什么問(wèn)題,也很簡(jiǎn)單明了,就是看起來(lái)有點(diǎn)丑,而且我還開(kāi)了比較高的桌面縮放,導(dǎo)致一屏幕幾乎都是這段if ... elif

看來(lái)看去越發(fā)覺(jué)得丑,先寫(xiě)個(gè)demo看看能不能跑通代碼。

方式1:字典映射

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

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版)》的最后一章提到了這個(gè)__init__subclass__,根據(jù)python官方文檔:

當(dāng)所在類(lèi)派生子類(lèi)時(shí)此方法就會(huì)被調(diào)用。cls 將指向新的子類(lèi)。如果定義為一個(gè)普通實(shí)例方法,此方法將被隱式地轉(zhuǎn)換為類(lèi)方法。傳給一個(gè)新類(lèi)的關(guān)鍵字參數(shù)會(huì)被傳給上級(jí)類(lèi)的 __init_subclass__。 為了與其他使用 __init_subclass__ 的類(lèi)兼容,應(yīng)當(dāng)去掉需要的關(guān)鍵字參數(shù)再將其他參數(shù)傳給基類(lèi)。

借助這個(gè)機(jī)制,可以在實(shí)現(xiàn)抽象基類(lèi)時(shí)自動(dòng)注冊(cè)子類(lèi),避免手動(dòng)維護(hù)注冊(cè)表。

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  # 自動(dòng)注冊(cè)子類(lèi)

# 子類(lèi)定義即自動(dòng)注冊(cè)
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

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

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

import importlib

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

補(bǔ)充

自動(dòng)注冊(cè)類(lèi)看起來(lái)炫,但是對(duì)代碼閱讀來(lái)說(shuō)不是很直觀。易讀還是美觀?這是一個(gè)問(wèn)題。

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

相關(guān)文章

最新評(píng)論

鄂温| 阳朔县| 东乡县| 江西省| 嘉义县| 合川市| 渭源县| 高雄县| 额尔古纳市| 利川市| 平和县| 河北区| 镇赉县| 疏附县| 秭归县| 根河市| 宾川县| 新密市| 保定市| 定日县| 宁化县| 康保县| 墨竹工卡县| 侯马市| 南雄市| 饶阳县| 汉源县| 云霄县| 北碚区| 宿迁市| 璧山县| 辛集市| 蓝田县| 沁源县| 建宁县| 甘孜县| 桓仁| 固阳县| 福州市| 崇文区| 抚松县|