定义 Class 覆盖 (__not__) 时出现问题
Problem at Define Class Override (__not__)
上下文
作为练习,我正在创建一个 Variable
class 来表示一个逻辑变量。它被声明为
class Variable(object):
""" Class for emulate logical variables. """
def __init__(self, valor, /, name='std var'):
self.name = name
if isinstance(valor, bool):
self.valor = valor
else:
raise Exception("Class Error: Constructor must receive a bool as first arg. ")
并在此 class 中覆盖了一些标准运算符并创建了基本的逻辑函数;比如and
, or
,not
def truth(self):
""" Overload de operacion de verdad. """
return self.valor
def __eq__(self, other):
""" Overload del operador =. """
return True if self.valor == other else False
def __not__(self):
""" Overload del operador (not). """
return True if self.valor else False
def __and__(self, other):
""" Overload del operador & (and). """
return True if (self.valor and other) else False
def __or__(self, other):
""" Overload del operador | (or). """
return True if (self.valor or other) else False
def show(self):
return "{} => {}".format(self.name, self.valor)
问题
最后我创建了一个测试,它引发了一个我无法弄清楚的有趣错误。这是测试代码
def test():
""" Testing proves. """
q = Variable(True, 'q')
p = Variable(False, 'p')
print("\nDadas {} y {} se da que".format(q.show(), p.show()))
# Checking __eq__
assert (q == q) == True
assert (q == p) == False
# Checking __and__
assert (q and q) == True
assert (q and p) == False
assert (p and p) == False
# checking __or__
assert (q or p) == True
assert (q or q) == True
assert (p or p) == False
# checking __not__
assert (not q) == False
assert (not p) == True, f'{p.show()=}'
并且它 运行 顺利地直到它引发下一个错误
assert (not p) == True, f'{p.show()=}'
AssertionError: p.show()='p => False'
我知道错误的出现是因为句子 (not p) == True
是假的。问题是,为什么?
我的想法和尝试
首先我认为 truth
覆盖它不起作用。所以我将所有 p
条目更改为 p.valor
并执行
>>> from Module import Variable
>>>
>>> p = Variable(False)
>>> if p.valor:
>>> print("Not works")
>>> else:
>>> print("Or yes")
Or yes
并且有效。然后我想到问题可能出在 __not__
上。所以我重写了几次都没有成功。所以我尝试了这个
>>> p = Variable(True)
>>> # check if its set correctly
>>> print("Y" if p.valor else "N")
Y
>>> # so p.valor its True. Check __not__
>>> not p
False
>>> # here it seems that `__not__` does work, but
>>> p = L.Variable(False)
>>> p.valor
False
>>> print("Y" if p.valor else "N")
N
>>> not p
False
看起来该功能仅在 p.valor = True
...
时有效
(编辑)
我...迷路了,但不会再迷路了。
根据DeepSpace的回答,我重写了重载函数。所以他们
def __bool__(self):
return self.valor
def __eq__(self, other):
return True if self.valor == other else False
def __not__(self):
return not(self.valor)
def __and__(self, other):
return True if (self and other) else False
def __or__(self, other):
return True if (self or other) else False
至此,顺利通过所有测试
__not__
不是 魔法方法,它不是 data model 的一部分,也不会被任何东西自动调用。
换句话说,not p
不调用p.__not__
。相反,它只是否定 p.__bool__
returns.
class Foo:
def __bool__(self):
print('In Foo.__bool__')
return True
print(not Foo())
产出
In Foo.__bool__
False
上下文
作为练习,我正在创建一个 Variable
class 来表示一个逻辑变量。它被声明为
class Variable(object):
""" Class for emulate logical variables. """
def __init__(self, valor, /, name='std var'):
self.name = name
if isinstance(valor, bool):
self.valor = valor
else:
raise Exception("Class Error: Constructor must receive a bool as first arg. ")
并在此 class 中覆盖了一些标准运算符并创建了基本的逻辑函数;比如and
, or
,not
def truth(self):
""" Overload de operacion de verdad. """
return self.valor
def __eq__(self, other):
""" Overload del operador =. """
return True if self.valor == other else False
def __not__(self):
""" Overload del operador (not). """
return True if self.valor else False
def __and__(self, other):
""" Overload del operador & (and). """
return True if (self.valor and other) else False
def __or__(self, other):
""" Overload del operador | (or). """
return True if (self.valor or other) else False
def show(self):
return "{} => {}".format(self.name, self.valor)
问题
最后我创建了一个测试,它引发了一个我无法弄清楚的有趣错误。这是测试代码
def test():
""" Testing proves. """
q = Variable(True, 'q')
p = Variable(False, 'p')
print("\nDadas {} y {} se da que".format(q.show(), p.show()))
# Checking __eq__
assert (q == q) == True
assert (q == p) == False
# Checking __and__
assert (q and q) == True
assert (q and p) == False
assert (p and p) == False
# checking __or__
assert (q or p) == True
assert (q or q) == True
assert (p or p) == False
# checking __not__
assert (not q) == False
assert (not p) == True, f'{p.show()=}'
并且它 运行 顺利地直到它引发下一个错误
assert (not p) == True, f'{p.show()=}'
AssertionError: p.show()='p => False'
我知道错误的出现是因为句子 (not p) == True
是假的。问题是,为什么?
我的想法和尝试
首先我认为 truth
覆盖它不起作用。所以我将所有 p
条目更改为 p.valor
并执行
>>> from Module import Variable
>>>
>>> p = Variable(False)
>>> if p.valor:
>>> print("Not works")
>>> else:
>>> print("Or yes")
Or yes
并且有效。然后我想到问题可能出在 __not__
上。所以我重写了几次都没有成功。所以我尝试了这个
>>> p = Variable(True)
>>> # check if its set correctly
>>> print("Y" if p.valor else "N")
Y
>>> # so p.valor its True. Check __not__
>>> not p
False
>>> # here it seems that `__not__` does work, but
>>> p = L.Variable(False)
>>> p.valor
False
>>> print("Y" if p.valor else "N")
N
>>> not p
False
看起来该功能仅在 p.valor = True
...
(编辑)
我...迷路了,但不会再迷路了。
根据DeepSpace的回答,我重写了重载函数。所以他们
def __bool__(self):
return self.valor
def __eq__(self, other):
return True if self.valor == other else False
def __not__(self):
return not(self.valor)
def __and__(self, other):
return True if (self and other) else False
def __or__(self, other):
return True if (self or other) else False
至此,顺利通过所有测试
__not__
不是 魔法方法,它不是 data model 的一部分,也不会被任何东西自动调用。
换句话说,not p
不调用p.__not__
。相反,它只是否定 p.__bool__
returns.
class Foo:
def __bool__(self):
print('In Foo.__bool__')
return True
print(not Foo())
产出
In Foo.__bool__
False