python bool()と_bool__

5753 ワード

最近pythonを勉強していて、忘れないように記録を作って、メモも共有して、参考にしています.
値の真偽を判断する場合、bool(object)メソッドを使用することが多く、オブジェクト(object)の真偽を判断し、TrueまたはFalseを返します.しかし、なぜbool()やlen()の方法を直接使うことができるのか、ずっと分からなかった.
元bool(object)は、実は呼び出しのobject._bool__メソッドの結果、オブジェクトが存在しない場合bool__メソッドを使用するとpythonが__を呼び出します.len__方法.0を返すとbool()はFalseを返し、そうでない場合はTrueを返します.デフォルトでは、カスタムクラスの__を除き、カスタムクラスのインスタンスは本物とみなされます.bool__および_len__方法には他の実装がある.
>>> a = 0
>>> dir(a)
['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']
>>>
ここでは、aがintクラスのインスタンスであるため、intクラスには__があるため、a変数を作成する際に参照してください.bool__方法.したがって、bool(a)が呼び出されると、実際にはaの__が使用されるbool__内装の方法.
>>> bool(a)
False
>>>
でaがstrなら?
>>> a = 'test'
>>> dir(a)
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
>>>
このときaはstrクラスの例であり、strクラスには__がない.bool__組み込みメソッドの場合、pythonは__を呼び出します.len__メソッドは、0を返すとbool()がFalseを返し、そうでない場合はTrueを返します.
>>> bool(a)
True
>>>
上はaのlenが0ではないのでTrueを返します.aを空の文字列として定義してみましょう.
>>> a = ''
>>> bool(a)
False
>>>
には、aの長さが0であるため、bool()はFalseを返すことがわかる.a長が0でない場合、結果はTrueです.
>>> a = 'test'
>>> bool(a)
True
>>>

クラスをカスタマイズしてみましょう.
>>> class A():
...     pass
...
>>> a = A()
>>> bool(a)
True
>>>
で得られた結果はTrueであり、カスタマイズされていないためです.bool__または_len__.デフォルトでカスタマイズされたクラスのインスタンスは、常に真のTrueとみなされます.
Aの_をカスタマイズします.bool__方法:
>>> class A():
...     def __bool__(self):
...             return False
...
>>> b = A()
>>> bool(b)
False
>>>
をカスタマイズしてください.len__方法:
>>> class A():
...     def __len__(self):
...             pass
...
>>> a = A()
>>> bool(a)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'NoneType' object cannot be interpreted as an integer
>>> len(a)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'NoneType' object cannot be interpreted as an integer
>>>
現在bool()メソッドはaにとって無効であることは明らかである.なぜなら私たちが定義した_len__メソッドはpassを返します.
if文を使用してみましょう.
>>> if a:
...     print('2222')
...
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'NoneType' object cannot be interpreted as an integer
>>>
if文はaを判断できないことが分かった.初心者なのでif文を実行するときにpythonがaの内部メソッドを自動的に呼び出したと推測した(後で検討する).同時にbool()もlen()も使えなくなりました.したがって、カスタムクラスの場合は、カスタム__も必要です.bool__または_len__またbool()とlen()メソッドをサポートするには、この2つのメソッドを合理的に定義しなければなりません.そうしないと、エラーが発生します.