python 基于实例的类型检查
python instance-based type checking
我有这样的代码:
def transform_incoming_json_item(item, things=[]):
if isinstance(item, list):
for thing in item:
things.append(process_thing(thing))
elif isinstance(item, dict):
things.append(process_thing(item))
return things
是否有更 pythonic 的方式来做到这一点,同时只对 process_thing 进行一次调用(同时保留类型检查和两种情况,循环与不需要循环)?
(注意:"more pythonic" 在编辑中添加以澄清问题。)
如何:对于 dict
情况,将字典转换为包含单个项目(字典对象)的列表:
def transform_incoming_json_item(item, things=[]):
if isinstance(item, dict): # <----
item = [item] # <----
if isinstance(item, list):
things.extend(process_thing(thing) for thing in item)
return things
注意:参数things
在定义时创建(仅一次)。换句话说,当调用函数 transform_incoming_json_item
时,事情并没有被初始化。
如果这不是您想要的,您需要执行以下操作:
def transform_incoming_json_item(item, things=None):
if things is None:
things = []
if isinstance(item, dict): # <----
item = [item] # <----
if isinstance(item, list):
things.extend(process_thing(thing) for thing in item)
return things
利用faltru将dict转成list的思路,可以进一步简化代码为:
def transform_incoming_json_item(item, things=None):
return ([] if things is None else things +
[process_thing(thing) for thing in (
item if isinstance(item, list) else
[item] if isinstance(item, dict) else [])])
如您所见,它相当紧凑。但是,如果列表理解这么长时间让您感到困惑或者不是您的事,那么您显然应该选择其他答案。就个人而言,我发现它们非常适合这种情况,但是 YMMV。
我有这样的代码:
def transform_incoming_json_item(item, things=[]):
if isinstance(item, list):
for thing in item:
things.append(process_thing(thing))
elif isinstance(item, dict):
things.append(process_thing(item))
return things
是否有更 pythonic 的方式来做到这一点,同时只对 process_thing 进行一次调用(同时保留类型检查和两种情况,循环与不需要循环)?
(注意:"more pythonic" 在编辑中添加以澄清问题。)
如何:对于 dict
情况,将字典转换为包含单个项目(字典对象)的列表:
def transform_incoming_json_item(item, things=[]):
if isinstance(item, dict): # <----
item = [item] # <----
if isinstance(item, list):
things.extend(process_thing(thing) for thing in item)
return things
注意:参数things
在定义时创建(仅一次)。换句话说,当调用函数 transform_incoming_json_item
时,事情并没有被初始化。
如果这不是您想要的,您需要执行以下操作:
def transform_incoming_json_item(item, things=None):
if things is None:
things = []
if isinstance(item, dict): # <----
item = [item] # <----
if isinstance(item, list):
things.extend(process_thing(thing) for thing in item)
return things
利用faltru将dict转成list的思路,可以进一步简化代码为:
def transform_incoming_json_item(item, things=None):
return ([] if things is None else things +
[process_thing(thing) for thing in (
item if isinstance(item, list) else
[item] if isinstance(item, dict) else [])])
如您所见,它相当紧凑。但是,如果列表理解这么长时间让您感到困惑或者不是您的事,那么您显然应该选择其他答案。就个人而言,我发现它们非常适合这种情况,但是 YMMV。