检查Python变量类型的最佳(惯用)方法是什么?
我需要知道Python中的变量是字符串还是dict。下面的代码有什么问题吗检查Python变量类型的最佳(惯用)方法是什么?,python,types,typechecking,Python,Types,Typechecking,我需要知道Python中的变量是字符串还是dict。下面的代码有什么问题吗 if type(x) == type(str()): do_something_with_a_string(x) elif type(x) == type(dict()): do_somethting_with_a_dict(x) else: raise ValueError 更新:我接受了阿维瑟的回答(尽管如果有人解释为什么isinstance比type(x)is更受欢迎,我会改变主意) 但感
if type(x) == type(str()):
do_something_with_a_string(x)
elif type(x) == type(dict()):
do_somethting_with_a_dict(x)
else:
raise ValueError
更新:我接受了阿维瑟的回答(尽管如果有人解释为什么isinstance
比type(x)is
更受欢迎,我会改变主意)
但感谢NakedFananic提醒我,使用dict(作为案例陈述)通常比使用if/elif/else系列更干净
让我详细说明一下我的用例。如果一个变量是一个字符串,我需要把它放在一个列表中。若它是一个dict,我需要一个唯一值的列表。以下是我的想法:
def value_list(x):
cases = {str: lambda t: [t],
dict: lambda t: list(set(t.values()))}
try:
return cases[type(x)](x)
except KeyError:
return None
如果首选
isinstance
,您将如何编写这个value\u list()
函数?应该可以工作-因此,您的代码没有问题。但是,也可以使用dict:
{type(str()): do_something_with_a_string,
type(dict()): do_something_with_a_dict}.get(type(x), errorhandler)()
你会说得更简洁、更通俗一点吗
编辑。。根据Avisser的建议,代码的工作原理也是这样的,并且看起来更好:
{str: do_something_with_a_string,
dict: do_something_with_a_dict}.get(type(x), errorhandler)()
Python中的内置类型具有内置名称:
>>> s = "hallo"
>>> type(s) is str
True
>>> s = {}
>>> type(s) is dict
True
顺便说一句,操作员是。然而,类型检查(如果您想这样称呼它)通常是通过在try-except子句中包装一个特定于类型的测试来完成的,因为重要的不是变量的类型,而是您是否可以用它做某些事情。type(dict())
说“创建一个新的dict,然后找出它的类型”。只说dict
更快。
但如果您只想检查类型,一种更惯用的方法是isinstance(x,dict)
请注意,isinstance
还包括子类(谢谢):
我认为最好是真的这样做
if isinstance(x, str):
do_something_with_a_string(x)
elif isinstance(x, dict):
do_somethting_with_a_dict(x)
else:
raise ValueError
2种替代形式,取决于您的代码,一种或另一种可能被认为比这更好。一是三思而后行
try:
one, two = tupleOrValue
except TypeError:
one = tupleOrValue
two = None
另一种方法来自Guido,是一种函数重载形式,它使代码更加开放
如果有人将unicode字符串传递给您的函数,会发生什么情况?还是从dict派生的类?还是实现类似dict接口的类?以下代码涵盖前两种情况。如果您使用的是Python2.6,那么您可能希望使用而不是
dict
,如所示
isinstance比type更受欢迎,因为当您将对象实例与其超类进行比较时,它的计算结果也为True,这基本上意味着您将永远不必将旧代码的特殊情况用于dict或str子类 例如:
>>> class a_dict(dict):
... pass
...
>>> type(a_dict()) == type(dict())
False
>>> isinstance(a_dict(), dict)
True
>>>
当然,在某些情况下,您可能不希望出现这种行为,但希望这些情况比您希望的情况要少很多。我一直在使用一种不同的方法:
from inspect import getmro
if (type([]) in getmro(obj.__class__)):
# This is a list, or a subclass of...
elif (type{}) in getmro(obj.__class__)):
# This one is a dict, or ...
我不记得为什么我用这个代替了iInstance,不过…我想我会选择鸭子打字法——“如果它像鸭子一样走路,它像鸭子一样嘎嘎叫,它就是鸭子”。这样,您就不必担心字符串是unicode还是ascii 以下是我将要做的:
In [53]: s='somestring'
In [54]: u=u'someunicodestring'
In [55]: d={}
In [56]: for each in s,u,d:
if hasattr(each, 'keys'):
print list(set(each.values()))
elif hasattr(each, 'lower'):
print [each]
else:
print "error"
....:
....:
['somestring']
[u'someunicodestring']
[]
欢迎这里的专家对ducktyping的这种用法发表评论,我一直在使用它,但最近被介绍到它背后的确切概念,对此我非常兴奋。所以我想知道这样做是否有点过分。*叹气*
不,python中的类型检查参数不是必需的。它是永远不会 必要的 如果您的代码接受字符串或dict对象,则您的设计将被破坏 这是因为如果你还不知道对象的类型 在你自己的程序中,你已经做错了什么 类型检查会损害代码重用并降低性能。有这样一种功能 根据所传递对象的类型执行不同的操作 容易出现错误,行为更难理解和维护 您有以下更明智的选择: 1) 创建一个函数
unique\u values
,该函数将DICT转换为唯一的值列表:
def unique_values(some_dict):
return list(set(some_dict.values()))
使函数假定传递的参数始终是列表。这样,如果需要向函数传递字符串,只需执行以下操作:
myfunction([some_string])
如果您需要通过口述,请执行以下操作:
myfunction(unique_values(some_dict))
这是您最好的选择,它干净、易于理解和维护。任何人
阅读代码可以立即理解正在发生的事情,而您没有
打字检查
2) 生成两个函数,一个接受字符串列表,另一个接受
格言。您可以在最方便的情况下在内部拨打一个电话
方法(myfunction\u dict
可以创建字符串列表并调用myfunction\u list
)
在任何情况下,都不要进行打字检查。这是完全没有必要的,只有
缺点。以一种不需要进行类型检查的方式重构代码。
无论从短期还是长期来看,这样做只会给您带来好处。您可能想查看typecheck。 Python的类型检查模块
这个包为Python函数、方法和生成器提供了强大的运行时类型检查工具。无需对语言进行自定义预处理器或更改,typecheck软件包允许程序员和质量保证工程师对其代码的输入和输出做出精确的断言。不,它不是更像Python,因为您应该使用isinstance内置函数。嘿,我知道“P”这个词会有煽动性。然而,我坚持我的答案,作为避免if-elif-else结构的替代方案。我同意。请参阅我编辑的问题。正如其他人所提到的,首选方法是使用isinstance内置函数。isinstance可以在任何类/类型上完成,包括您自己定义的类/类型,而内置类型名称的数量有限,即“isinstance(x,dict)”优于“type(x)is dict”?为什么?@Daryl@Dustin Dead link…这似乎可能会产生误报——如果我们
myfunction([some_string])
myfunction(unique_values(some_dict))