True
还是False
:def stringify(value):
"""Returns the string representation of the value."""
if value is None:
return '-'
if value is True:
return '✓'
if value is False:
return '✗'
return str(value)
我知道,在大多数情况下,您只需要事实是,您只需要执行
if value:
即可。但这并不能满足要求,因为我希望以十进制形式显示零个int
s和float
s以及空的list
s,set
s dict
s。上面的代码是否可以接受?首先使用
isinstance(value, bool)
检查,然后再使用if value:
吗?最令人惊讶的方式是什么?到终端输出:
MariaDB→peewee→API→终端
示例输出:
$ termutil ls -T 1000
ID TID CID VID OS IPv4 Address Deployed Testing Tainted Address Annotation
214 1 1000 - HIDSL latest XX.Y.Z.75 - ✓ ✗ Musterstraße 42, 123456 Irgendwo -
215 2 1000 - HIDSL latest XX.Y.Z.76 - ✓ ✗ Musterstraße 42, 123456 Irgendwo -
216 3 1000 - HIDSL latest XX.Y.Z.77 - ✓ ✗ Musterstraße 42, 123456 Irgendwo -
217 4 1000 - HIDSL latest XX.Y.Z.78 - ✓ ✗ Musterstraße 42, 123456 Irgendwo -
218 5 1000 - HIDSL latest XX.Y.Z.79 - ✓ ✗ Musterstraße 42, 123456 Irgendwo -
219 6 1000 - HIDSL latest XX.Y.Z.80 - ✓ ✗ Musterstraße 42, 123456 Irgendwo -
330 7 1000 399 HIDSL latest XX.Y.Z.182 - ✗ ✗ Musterstraße 42, 123456 Irgendwo -
508 8 1000 - HIDSL latest XX.Y.Z.189 - ✗ ✗ N/A -
#1 楼
由于代码段非常小,并且缺少其他上下文,因此很难确定在代码其他地方可能出现的扩展问题。因此,如果您想要一个更合适的答案,则应添加更多代码。是的,这很好。这样只会增加额外的缩进级别而没有理由。
#2 楼
我个人会使用字典,因为它们几乎是标准的switch语句。如果您仅使用仅以
True
作为键的普通字典,那么它对于'✓'
和True
。因此您可以创建一个字典,键为值和类型的元组。您想:
_stringify_values = {
(type(None), None): '-',
(bool, True): '✓',
(bool, False): '✗'
}
def stringify(value):
try:
return _stringify_values[(type(value), value)]
except (KeyError, TypeError):
return str(value)
如果您打算大量使用它,也可以制作一个简单的类来包含所有特殊逻辑。通过使用
1
:_stringify_values = {
None: '-',
True: '✓',
False: '✗'
}
_stringify_values = {(type(k), k): v for k, v in _stringify_values.items()}
评论
\ $ \ begingroup \ $
这是在过度设计的解决方案中查找不存在的问题。
\ $ \ endgroup \ $
–将
18年7月20日在1:32
\ $ \ begingroup \ $
除了一般的过度设计之外,为什么在世界上您会捕获KeyError而不是使用return _stringify_values.get((type(value),value),str(value))
\ $ \ endgroup \ $
–约翰内斯·皮尔(Johannes Pille)
18年7月20日在6:35
\ $ \ begingroup \ $
@JohannesPille因为在密钥无法散列时已经需要捕获TypeError;因此无需使行的可读性降低。
\ $ \ endgroup \ $
–301_Moved_Permanently
18年7月20日在7:11
\ $ \ begingroup \ $
@Will我不认为使用字典会导致尝试过度。该类是,这就是为什么我给它加上“如果您打算大量使用它”的原因。
\ $ \ endgroup \ $
– Peilonrayz
18年7月20日在9:02
#3 楼
即使return
如果一个匹配项都缩短了链的长度,我还是更喜欢在这里使用elif
链,因为它更明显,但是YMMV(尤其是自动短绒):br />除此之外,没有真正的选择,因为所有其他方法都将因
0
和False
之间的差异而失败,而这只能通过is
或不可散列的类型(例如list
)才能获得。我看到的唯一另一种可能性是在转换为
True, False, None
后替换str
的值,不使用str.translate
,但是这将无法区分None
和"None"
。评论
\ $ \ begingroup \ $
实际上,由于pylint发出的噪音,我实际上摆脱了小精灵。
\ $ \ endgroup \ $
–理查德·诺伊曼(Richard Neumann)
18年7月19日在11:56
\ $ \ begingroup \ $
就是这样一种情况:告诉短绒小动物安静,而不是修改您的代码以使其安逸。
\ $ \ endgroup \ $
–chepner
18年7月19日在15:38
\ $ \ begingroup \ $
pylint的默认设置很糟糕。
\ $ \ endgroup \ $
– user2357112支持Monica
18年7月19日在19:32
\ $ \ begingroup \ $
IMO使用elif实际上会使代码更糟,因为它意味着可到达的else分支。引入这样的重言式并不能使我澄清任何事情:每次我阅读带有冗余语句的代码时,都会对那些写有清楚自己的控制流思维模型的人失去一点信心。代码可能“太聪明”,但有时也可能...太笨了?
\ $ \ endgroup \ $
–将
18年7月20日在1:22
\ $ \ begingroup \ $
@如我所说,YMMV。我通常同意您的意见,但在这里我喜欢它,因为一眼就可以看出案件是互斥的。对于原始的if链,这对我来说不那么明显。
\ $ \ endgroup \ $
–地狱
18年7月20日在6:01
#4 楼
我可能会使用嵌套的条件表达式,这些条件表达式可以很干净地格式化:匹配的情况。评论
\ $ \ begingroup \ $
-1表示内联条件,而+2表示“对于少量硬编码的检查,可读性胜于线性搜索以找到匹配的大小写。”完全同意。
\ $ \ endgroup \ $
– Quelklef
18年7月19日在16:53
#5 楼
关于函数名称和文档字符串的说明:def stringify(value):
"""Returns the string representation of the value."""
stringify
:什么值?它必须是数字值吗?任何类型的值,但没有对象?变量名并不能完全清楚显示该变量名。返回该值的字符串表示形式。因为阅读后我不知道...
允许使用哪些值?有限制吗?
定义值的“字符串表示形式”的原因是什么?仅
to_string
就有很多可能的表示形式。从value
到完整序列化,嵌套结构,对象等也可以具有许多可能的表示形式。有什么区别?某些数据类型是否有特殊处理?我不知道您对
float
的表示形式将是一个Unicode字符,而不是[object]
,str
或unicode
,它们将遵循最少的原则。默认处理其他所有内容。如果输入不是布尔值,则可能为True
并引发"True"
。#6 楼
要消除由'-'
和'[1, 2]'
之类的输入引起的歧义,我建议将str(value)
调用替换为repr(value)
调用。如果您希望将其扩展到线性搜索可能导致不必要的延迟的地步,您可以将需要使用以下单例中的
id
来避免在将不可散列的类型进行字符串化时出现问题:try:
# Using the id() of singletons to support unhashable types
return appropriately_named_lookup_table[id(value)]
except KeyError:
return repr(value)
如果最终这样做,请确保对此进行记录,并记住尽管它似乎适用于整数
in range(-5, 256)
,但这仅是CPython实现的细节。评论
\ $ \ begingroup \ $
+1代表repr,但是对于“用户”来说,代码似乎比“开发者”更有用
\ $ \ endgroup \ $
–吉列什·乔汉(Grijesh Chauhan)
18年7月20日在6:47
\ $ \ begingroup \ $
OP表示模棱两可是不可避免的。
\ $ \ endgroup \ $
– wizzwizz4
18年7月20日在6:50
\ $ \ begingroup \ $
正如我在上面评论的那样,模棱两可根本不是问题。相反,我不希望'使我的弦泛滥。
\ $ \ endgroup \ $
–理查德·诺伊曼(Richard Neumann)
18年7月20日在13:00
\ $ \ begingroup \ $
您可以使用defaultdict而不是捕获异常。
\ $ \ endgroup \ $
– allo
18年7月23日在7:33
\ $ \ begingroup \ $
@allo真的吗?我不知道该支持传递参数!但是不,因为它必须使用从id强制转换的ctypes,它恰好是CPython中的地址,但不是必需的。
\ $ \ endgroup \ $
– wizzwizz4
18年7月23日在21:47
评论
我个人不喜欢这里的最终案例。如果我输入“-”,“✓”或“✗”怎么办?返回的值将是不明确的。或者,您可以指定您不接受文档字符串中的字符串或键入合同。@LukeSawczak如果对象可能是字符串,则在将对象转换为字符串时始终会有歧义。您的示例也适用于[]→“ []”和“ []”→“ []”等。
-除非您发现了这种情况并为其定义了行为:)
@LukeSawczak在我的用例中,我不介意这种歧义。
最好的答案是您的问题。我在下面看不到任何改进。