2016-11-20 46 views
0

我经常发现自己写的多语句表达式在运行时验证类型的变量。例如,假设我想验证一个特定的输入是富对象的列表,我可能会写下面的表达式:有没有办法做判断的对象是在运行时pep484风格表达的“实例”?

assert(_isinstance(x, list) and all(_isinstance(y, Foo) for y in x)) 

我宁愿能写类似:

# pseudocode 
_assert(isinstance(x, typing.List[Foo])) 

换句话说,我要问x是美孚的实例的列表。

如果可以作出努力,这将是更好,因为Pep484语法简明地指定类型的嵌套结构的好方法。当然,我们都知道,这是没有办法的办法Python的内置isinstance函数的工作......但只是我的梦想了一会儿:

我们都熟悉,如果外返回true的isnstance功能一个结构类型是一个类的实例:

# real python: 
isinstance(["a", "b", "c"], list) => True 

但是假设我想要做更深入的检查:我想这样做:

# pseudocode: 
import typing 
_isinstance("x", str) => True 
_isinstance(["a", "b", "c"], typing.List[str]) => True 
_isinstance(["a", "b", "c"], typing.List[float]) => False 
_isinstance([{"x":3}], typing.List[typing.Map[str,int]]) => True 

这样的想法是函数如果第一个参数完全对应于Pep484风格表达式,则返回True第二个论点的离子。

当然,有些人会指出,明确的静态和运行时类型检查违背“鸭打字”的精神。这是真的 - 但没有用。有时你确实想要验证输入的结构。随着项目变得越来越大,你有时候想你想要什么,你正在处理,并在其他时间类型的鸭打字给你的灵活性,肯定知道的能力。

因此,这里是我的问题:有没有人见过的方式来比较类型Pep484风格的表达式?如果已经有一个图书馆或功能来做它,那么我宁愿不重新发明轮子。也许打字库已经有办法做到这一点。请指点我吧!

+0

您已经使用'你的所有假设的例子向后isinstance'。不是说如果你翻动它,它会起作用。 'isinstance'不会做你想做的。 – ShadowRanger

+0

这是向后一个例子 - 我已经纠正了,谢谢! –

+0

在另一个示例中,您只是将其作了倒退。原型是'isinstance(OBJ,type_or_tuple_of_types)','未isinstance(type_or_tuple_of_types,OBJ)'。测试'x'是类型还是'list'的子类型是'isinstance(x,list)',而不是'isinstance(list,x)'。 – ShadowRanger

回答

-1

你可能已经做了这样的:

def _isinstance(var, type): 
    if not isinstance(var, type): 
     return False 

    if isinstance(var, Iterable) and not isinstance(var, Generator): 
     return all(any(isinstance(v, t) for t in type.__parameters__) for v in var) 

    return True 

当然,这不是比你已经得到了很大的不同,但它给做assert(isinstance(x, List[Foo]))的“简单”。这里x必须是可迭代的。

注意,一个不能确定各类发电机将产生的数据,而不通过它迭代,从而丧失了所有的数据。

Python是鸭类型的和不关心类型多。如果有东西像鸭子一样嘎嘎地响,那么它就是Python的鸭子。

+0

嗨,说“Python是duck-typed,并不关心类型”不是特别有用。有时你必须确认类型(例如在界面边界)。在其他时候,我们可以放松一下,并相信鸭子打字。我同意在一次性遍历结构(例如Generators)的情况下,您不能验证输入而不渲染对象有用,但是这是真的,但是您想验证您的类型! –

+0

@SalimFadhley,好吧,这是事实...如果你发现自己需要检查Python中的类型,你可能会做错误的方式,并可能想切换到某种强类型语言,尽管在C++中为例如,就我而言,显式检查类型(例如,使用“if”子句),被认为是不好的做法。 – ForceBru

+0

我很好奇为什么你认为这是一个不恰当的问题:Python 3.5.x为了指定类型(用于类型提示)明确指定了一个迷你语言,我的问题是是否有一种方法来使用这些相同的表达式在运行时验证类型。这不是每个项目都需要的东西,但是对我而言这将是非常方便的 - 这是一个老式的项目,它有很多结构化数据。 –

相关问题