发现了 Python 一个奇怪的特性

2020-11-05 23:52:38 +08:00
 AbcHiyi

正常来说使用 bool 函数判读一个自定义的对象只要对象没有实现 bool 方法因该是默认作为 true 处理的吧。 但是奇怪的是在 3.8.5 版本中我自定义的一个对象在某些情况下作为 true 某些情况下作为 false 处理,但是我确定没有实现__bool__方法.这让我很费解。仔细观察发现,这个对象含有有效数据时作为 true 处理,不含有时作为 false 。这让我很费解。调用数据有关的至于两个方法,一个 json 方法,一个 text 方法。在 josn 在任何情况下都不会输出 None,text 方法在某些情况下会输出空字符串。但是测试后发现与这两个方法没有关系。实在不明白究竟是哪里出了差错。

4213 次点击
所在节点    Python
16 条回复
askfermi
2020-11-05 23:54:56 +08:00
When this method is not defined, __len__() is called, if it is defined, and the object is considered true if its result is nonzero. If a class defines neither __len__() nor __bool__(), all its instances are considered true.

https://docs.python.org/3/reference/datamodel.html#object.__bool__
AbcHiyi
2020-11-06 00:01:13 +08:00
@askfermi 这就是问题所在了,我既没有定义 __bool__方法也没有定义__len__方法,也没有定义别的东西。也许是其它问题。
mec
2020-11-06 00:04:47 +08:00
贴代码呀
Kobayashi
2020-11-06 00:10:41 +08:00
@mec 贴啥代码啊。大家盲赌,人人都有机会,岂不美哉?
freakxx
2020-11-06 01:45:59 +08:00
先吐槽下,像这样的排版和问问题的手法,我看到了一些些喂我吃屎的同事的身影。
出错了,既不给 request,也不给 response,也不给细节。

可以看下是不是继承了基础类型,比如 str, 导致空值的时候为 False
比如这样写
class Value(str)
laike9m
2020-11-06 01:59:11 +08:00
贴代码,请
AbcHiyi
2020-11-06 03:42:06 +08:00
@Kobayashi @laike9m @askfermi @freakxx 抱歉抱歉 忘记了 大概是这样的 没有继承

class Semantic:

@equal_language_check
def __init__(self, from_lang, to_lang, reper_text):
self.reper_text = reper_text
self.from_lang = from_lang
self.to_lang = to_lang

template = Conf().template_of_semantic(
fromlang=from_lang,
text=reper_text,
tolang=to_lang,
)

self.__data__ = requests.post(
**template
).json()[0]['translations']

def __repr__(self):
return F'"{self.reper_text}"({self.from_lang})-->({self.to_lang})'

def text(self) -> str:
data = self.json()['semantic']
text = '\n'.join([F'{k}:{",".join(v)}' for k, v in data.items()])
return text

def json(self) -> dict:
semantics = {}
for i in self.__data__:
temp = []
for i_i in i['backTranslations']:
temp.append(i_i['displayText'])
semantics[i['displayTarget']] = temp
return {
'from': self.from_lang,
'semantic': semantics,
'to': self.to_lang
}
AbcHiyi
2020-11-06 03:44:55 +08:00
class Semantic:

@equal_language_check
def __init__(self, from_lang, to_lang, reper_text):

def __repr__(self):

def text(self) -> str:

def json(self) -> dict:

这好像没法弄格式,大致结构就是这样的
ericls
2020-11-06 04:30:14 +08:00
Python 很动态 anything is accessible at any time. 你得贴完整的代码
catxo
2020-11-06 09:53:44 +08:00
text 返回空字符
那应该去检查 self.json()['semantic'] 是不是空
所以应该检查 self.__data__是不是空
所以应该检查 requests.post 返回什么东西
从头到尾跟 dunder method 都没有关系
zone10
2020-11-06 09:56:41 +08:00
问题的附录可以用 markdown 格式的, 怕你不知道跟你提一嘴, 没排版好的代码就懒得看了
freakxx
2020-11-06 13:16:52 +08:00
@zone10 #11
这样的口气,显得你能?
freakxx
2020-11-06 13:19:06 +08:00
@AbcHiyi #8

感觉没办法判断出问题,

你可以看两个地方
一个是 equal_language_check 这里有没写了什么,可能做了一些属性的操作
另外就是在对象输出的地方,看下__dir__ 是不是包含了 __bool__ 或 __len__ 这样的方法
zone10
2020-11-09 09:54:57 +08:00
@freakxx 贴代码要排好版是程序员的基本素养, 对大家都好, 当然你不在乎困难乐于助人当我没说
JSPIXiaoHei
2020-11-09 20:35:54 +08:00
写个测试,传一堆东西进去,看看到底哪个不一样,然后再调试跟进,看看问题出在哪
AbcHiyi
2020-11-10 20:59:33 +08:00
@zone10 好的知道了,下次注意。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/722197

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX