在 Python 中强制使用函数参数类型?
Posted
技术标签:
【中文标题】在 Python 中强制使用函数参数类型?【英文标题】:Force a function parameter type in Python? 【发布时间】:2013-01-29 06:33:07 【问题描述】:我在 Python 类中有一个函数,可以将接口添加到列表中。
def RegisterAsListener(self, inListener):
self.__TransitListeners.append(inListener)
这很好,因为一个类只需要从我的接口继承,获取这个对象,并为所有更新注册自己。
class ITransit():
def TransitUpdate(self, data):
raise NotImplementedError("You must define this function.")
(假设我正确地制作了一个界面)
由于我不是这个项目中唯一的人,我不希望有人使用不正确的数据类型调用 RegisterAsListener 函数。我可以输入代码来检查寄存器函数中的类型,但如果编译器只是在程序员试图输入不正确的数据类型时对他们大喊大叫,那会更容易。
def RegisterAsListener(self, IListener inListener):
self.__TransitListeners.append(inListener)
有什么办法吗?
【问题讨论】:
if the compiler just yelled at the programmer
... 什么编译器?
使用abc
模块来定义一个对象应该实现什么。
否则,Python 是一种动态类型 语言,它不为您强制执行对象类型。
【参考方案1】:
因为我不是这个项目中唯一的人,所以我不想要任何人 使用不正确的数据类型调用 RegisterAsListener 函数
彻底记录函数,然后让不正确的参数引发异常。 RegisterAListener
的用户应该能够使用文档来了解函数需要什么样的数据,并且 - 如果给定的参数不正确 - 产生的异常应该清楚 RegisterAListener
的用户做错了什么。
【讨论】:
您可以考虑使用Python Annotations 作为文档的一部分,作为一种自我文档。 逻辑答案,如果问题是问如何强制执行数据类型,为什么每个人都说不要,PYTHON 是动态的。您并不总是能够控制您将收到哪些对象,所以这是一个非常合理的问题。【参考方案2】:虽然我强烈建议不要这样做,并且只使用抽象基类 (http://docs.python.org/2/library/abc.html) 强制执行某些方法,但这是可能的。
这是一个关于如何做类似事情的例子:http://www.artima.com/weblogs/viewpost.jsp?thread=101605
# mm.py
registry =
class MultiMethod(object):
def __init__(self, name):
self.name = name
self.typemap =
def __call__(self, *args):
types = tuple(arg.__class__ for arg in args) # a generator expression!
function = self.typemap.get(types)
if function is None:
raise TypeError("no match")
return function(*args)
def register(self, types, function):
if types in self.typemap:
raise TypeError("duplicate registration")
self.typemap[types] = function
def multimethod(*types):
def register(function):
function = getattr(function, "__lastreg__", function)
name = function.__name__
mm = registry.get(name)
if mm is None:
mm = registry[name] = MultiMethod(name)
mm.register(types, function)
mm.__lastreg__ = function
return mm
return register
if hasattr(function, "__lastreg__"):
function = function.__lastreg__
以及使用它的代码:
import mm
@mm.multimethod(int)
def spam(a):
print 'Calling the int method'
print '%s: %r' % (type(a), a)
@mm.multimethod(float)
def spam(a):
print 'Calling the float method'
print '%s: %r' % (type(a), a)
spam(5)
spam(5.0)
示例输出:
Calling the int method
<type 'int'>: 5
Calling the float method
<type 'float'>: 5.0
【讨论】:
逻辑答案,如果问题是问如何强制执行数据类型,为什么每个人都说不要,PYTHON 是动态的。您并不总是能够控制您将收到哪些对象,所以这是一个非常合理的问题。以上是关于在 Python 中强制使用函数参数类型?的主要内容,如果未能解决你的问题,请参考以下文章
如何强制函数参数为相同类型并且不允许使用类型构造函数匹配给定类型?