Type deduction in Python
在python中,是否有更好的方法来确定函数参数是单个数字还是数字列表。目前我正在使用通道控制流异常的副作用,但它看起来并不优雅:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | def buildPattern( NumberOrList, Framework ): FinalPattern = '-->' try: ListLen = len(NumberOrList) #if this is a list, program flow will reach this point I = 0 for Char in Framework: if Char == 'x': FinalPattern = FinalPattern + ' ' + str(NumberOrList[I]) I = (I+1) % ListLen else: FinalPattern = FinalPattern + ' ' except: #if we reach this point, we don't have a list... (or some other problem) for Char in Framework: if Char == 'x': FinalPattern = FinalPattern + ' ' + str(NumberOrList) else: FinalPattern = FinalPattern + ' ' return FinalPattern print buildPattern( 3,'x x x x x x x x ' ) #single number call print buildPattern( [1,3,5], 'x x x x x x x x ' ) #list call |
您可以使用异常处理来完成这项工作,但正如您所说,这并不十分优雅。此外,如果经常引发异常,那么使用显式测试就不那么有效了。
实际上,重新设计代码会更优雅。;)因为python允许您定义一个函数,其中arg可以是一个数字或一个列表,这并不意味着它是一个好主意。正如您所发现的,它往往会使函数的内部逻辑更加复杂,并且常常导致不同执行路径中的重复代码。但是无论如何…
测试arg的干净方法是查看它是否是一个iterable,您可以使用
顺便说一句,使用"裸"
此外,最好遵循PEP-0008样式指南。它使其他人更容易阅读您的代码。
这里有一个更紧凑的函数版本,使用PEP-0008样式名编写。它使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | from __future__ import print_function from collections import Iterable from itertools import cycle def build_pattern(source, framework): if not isinstance(source, Iterable): source = [source] source = cycle(map(str, source)) final_pattern = ['-->'] for char in framework: final_pattern.append(next(source) if char == 'x' else ' ') return ' '.join(final_pattern) print(build_pattern(3, 'x x x x x x x x ')) #single number call print(build_pattern([1, 3, 5], 'x x x x x x x x ')) #list call print(build_pattern('abcde', 'x x x x x x x x ')) #string call |
输出
1 2 3 | --> 3 3 3 3 3 3 3 3 --> 1 3 5 1 3 5 1 3 --> a b c d e a b c |
正如VPFB在注释中提到的,字符串是不可更改的,所以如果您将一个字符串传递给my
你为什么不试试这个
1 2 3 4 5 | def buildPattern(NumberOrList, Framework): if isinstance(NumberOrList, list): # This is list else: # This is number |
这是PEP-8 Python样式指南推荐的,而不是类型(obj)
参考文献:
https://www.python.org/dev/peps/pep-0008/编程建议
只需在函数顶部使用带有IsInstance的if语句:
1 2 3 4 5 6 | if isinstance(NumberOrList, int): # Its a number elif isinstance(NumberOrList,list): # Its a list else: # Its something you dont want |