根据对象类型选择 class 方法的 Pythonic(OO) 方式
Pythonic(OO) way to choose class method depending on the type of object
是否有更好的 Pythonic / 面向对象 方法来选择在 运行时间,取决于对象的类型,因为使用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
对于我在这里要做的事情,还有什么技术术语吗?
我认为这可能与单调度、函数重载或多态性有关,但我不确定。
这确实是 single-dispatch,Python 通过 functools
模块支持。不需要 class。
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
,它将在方法的 second 参数上分派,跳过隐式提供的实例或 class 参数。
是否有更好的 Pythonic / 面向对象 方法来选择在 运行时间,取决于对象的类型,因为使用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
对于我在这里要做的事情,还有什么技术术语吗? 我认为这可能与单调度、函数重载或多态性有关,但我不确定。
这确实是 single-dispatch,Python 通过 functools
模块支持。不需要 class。
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
,它将在方法的 second 参数上分派,跳过隐式提供的实例或 class 参数。