【问题标题】:Pythonic(OO) way to choose class method depending on the type of objectPythonic(OO)根据对象类型选择类方法的方式
【发布时间】:2019-12-05 16:20:25
【问题描述】:

根据对象的类型,因为使用type() 方法不被认为是优雅(?)

我为我正在使用的三种数据类型编写了以下代码。它基本上将不同的函数作为值存储在字典中,并将其与其对应的对象类型作为键配对:

import pathlib
import _io

########################################
class choose_for :

    def __init__(self, var):
        func_dict = {str:self.func1, pathlib.WindowsPath:self.func2, _io.TextIOWrapper:self.func3}
        self.func = func_dict[type(var)]

    def func1(self) :
        print("Because it is for STRING like \n")

    def func2(self) :
        print("Because it is for PATH like \n")

    def func3(self) :
        print("Because it is for FILE_POINTER like \n")

    def execute(self):
        print("This object will be executed by : ", self.func)
        self.func()

########################################
var1 = str("something")

var2 = pathlib.Path()

var3 = _io.open("file.txt")

########################################
chosen1 = choose_for(var1)
chosen1.execute()

chosen2 = choose_for(var2)
chosen2.execute()

chosen3 = choose_for(var3)
chosen3.execute()

########################################
var3.close()

它给出以下输出:

This object will be executed by :  <bound method choose_for.func1 of <__main__.choose_for object at 0x0000020A150A3088>>
Because it is for STRING like

This object will be executed by :  <bound method choose_for.func2 of <__main__.choose_for object at 0x0000020A1509EFC8>>
Because it is for PATH like

This object will be executed by :  <bound method choose_for.func3 of <__main__.choose_for object at 0x0000020A15276B48>>
Because it is for FILE_POINTER like

还有什么技术术语,我想在这里做什么? 我认为这可能与单调度、函数重载或多态有关,但我不确定。

【问题讨论】:

标签: python python-3.x class polymorphism single-dispatch


【解决方案1】:

这确实是single-dispatch,Python 通过functools 模块支持它。不需要上课。

from functools import singledispatch


@singledispatch
def execute(arg):
    print(f"something with type {type(arg)}")

@execute.register(str):
def _(arg):
    print("Because it is for STRING like \n")

@execute.register(pathlib.Path):
def _(arg):
    print("Because it is for PATH like \n")

@execute.register(io.FileIO)
def _(arg):
    print("Because it is for FILE_POINTER like \n")

测试一下,你会看到

>>> execute("something")
Because it is for STRING like
>>> execute(pathlib.Path())
Because it is for PATH like
>>> execute(_io.open("file.txt"))
Because it is for FILE_POINTER like
>>> execute(3)
something with type <class 'int'>

要对方法使用单次分派,请使用singledispatchmethod,它将在方法的第二个参数上分派,跳过隐式提供的实例或类参数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-21
    • 1970-01-01
    • 1970-01-01
    • 2016-07-31
    • 2013-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多