我需要知道Python中的变量是字符串还是字典。下面的代码有问题吗?
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
更新:我接受avisser的答案(尽管如果有人解释为什么isinstance比type(x) is更受欢迎,我会改变主意)。
但是感谢nakedfanatic提醒我,使用dict(作为case语句)通常比使用if/elif/else系列更简洁。
让我详细说明我的用例。如果一个变量是一个字符串,我需要把它放在一个列表中。如果是字典,我需要一个唯一值的列表。这是我想到的:
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_list()函数?
*叹息*
不,python中不需要类型检查参数。从来没有
必要的。
如果您的代码接受字符串或dict对象,那么您的设计就坏了。
这是因为如果你不知道一个对象的类型
在你自己的程序中,你已经做错了一些事情。
类型检查会损害代码重用并降低性能。具有这样的功能
根据传递的对象类型执行不同的操作
容易出现错误,并且行为难以理解和维护。
你有以下更理智的选择:
1)创建一个函数unique_values,将字典转换为唯一的值列表:
def unique_values(some_dict):
return list(set(some_dict.values()))
让你的函数假设传递的参数总是一个列表。这样,如果你需要传递一个字符串给函数,你只需要这样做:
myfunction([some_string])
如果你需要传递一个字典,你可以这样做:
myfunction(unique_values(some_dict))
这是你最好的选择,它是干净的,容易理解和维护。任何人
阅读代码可以立即理解发生了什么,而您没有
typecheck。
2)创建两个函数,一个接受字符串列表,另一个接受字符串列表
字典。您可以在最方便的情况下,在内部打电话给另一个
方法(myfunction_dict可以创建字符串列表并调用myfunction_list)。
在任何情况下,都不要进行打字检查。这是完全不必要的,只有
缺点。以一种不需要类型检查的方式重构代码。
从短期和长期来看,这样做只会带来好处。
*叹息*
不,python中不需要类型检查参数。从来没有
必要的。
如果您的代码接受字符串或dict对象,那么您的设计就坏了。
这是因为如果你不知道一个对象的类型
在你自己的程序中,你已经做错了一些事情。
类型检查会损害代码重用并降低性能。具有这样的功能
根据传递的对象类型执行不同的操作
容易出现错误,并且行为难以理解和维护。
你有以下更理智的选择:
1)创建一个函数unique_values,将字典转换为唯一的值列表:
def unique_values(some_dict):
return list(set(some_dict.values()))
让你的函数假设传递的参数总是一个列表。这样,如果你需要传递一个字符串给函数,你只需要这样做:
myfunction([some_string])
如果你需要传递一个字典,你可以这样做:
myfunction(unique_values(some_dict))
这是你最好的选择,它是干净的,容易理解和维护。任何人
阅读代码可以立即理解发生了什么,而您没有
typecheck。
2)创建两个函数,一个接受字符串列表,另一个接受字符串列表
字典。您可以在最方便的情况下,在内部打电话给另一个
方法(myfunction_dict可以创建字符串列表并调用myfunction_list)。
在任何情况下,都不要进行打字检查。这是完全不必要的,只有
缺点。以一种不需要类型检查的方式重构代码。
从短期和长期来看,这样做只会带来好处。
Type (dict())表示“创建一个新的dict,然后找出它的类型”。直接说dict会更快。
但如果你只是想检查类型,更习惯的方法是isinstance(x, dict)。
注意,isinstance也包括子类(感谢Dustin):
class D(dict):
pass
d = D()
print("type(d) is dict", type(d) is dict) # -> False
print("isinstance (d, dict)", isinstance(d, dict)) # -> True