Python内置的bool方法__ror__有什么作用?

13

在交互式解释器中,如果按以下顺序输入,您可以看到一些非常有趣的东西:

1)help()

2)modules

3)__builtin__

阅读输出一段时间后,我发现在 class bool 中有以下几行内容:

__or__(...)
    x.__or__(y) <==> x|y

然后稍后:

__ror__(...)
    x.__ror__(y) <==> y|x

这种最后一种方法似乎描述了反向或。为什么会有这种方法?可能会导致__or__(...)返回与__ror__(...)不同的任何东西是什么?


3
在https://dev59.com/BnE95IYBdhLWcg3wPbZ7中已回答。 - synthesizerpatel
请看这里:https://docs.python.org/2/reference/datamodel.html#emulating-numeric-types - Chrispresso
请查看此项目示例:https://github.com/JulienPalard/Pipe - Ziyuan
2个回答

27
假设你编写了自己的整数类,并希望它能与内置的整数一起使用。你可以定义 __or__ 方法。
class MyInt(int):

    def __or__(self, other):
        # Not a recommended implementation!
        return self | int(other)

这样,您就可以编写像这样的代码:

# Because this is equivalent to MyInt.__or__(MyInt(6), 7)
MyInt(6) | 7

然而,Python 不知道该怎么做。
# First interpretation is int.__or__(7, MyInt(6))
7 | MyInt(6)

因为 int.__or__ 不知道如何处理 MyInt 的实例。在这种情况下,Python 会交换操作数的顺序并尝试进行操作。

MyInt.__ror__(MyInt(6), 7)

也就是说,查找右侧参数类中交换版本的魔术方法。

2

以下是在 REPL 中的实际用途:

假设您想要检查一个对象。这里我将使用 time 模块作为示例。

>>> import time
>>> vars(time)
{'timezone': 0, '_STRUCT_TM_ITEMS': 11, '__package__': '', 'mktime': <built-in function mktime>, 'altzone': 0, '__doc__': 'This module provides various functions to manipulate time values.\n\nThere are two standard representations of time.  One is the number\nof seconds since the Epoch, in UTC (a.k.a. GMT).  It may be an integer\nor a floating point number (to represent fractions of seconds).\nThe Epoch is system-defined; on Unix, it is generally January 1st, 1970.\nThe actual value can be retrieved by calling gmtime(0).\n\nThe other representation is a tuple of 9 integers giving local time.\nThe tuple items are:\n  year (including century, e.g. 1998)\n  month (1-12)\n  day (1-31)\n  hours (0-23)\n  minutes (0-59)\n  seconds (0-59)\n  weekday (0-6, Monday is 0)\n  Julian day (day in the year, 1-366)\n  DST (Daylight Savings Time) flag (-1, 0 or 1)\nIf the DST flag is 0, the time is given in the regular time zone;\nif it is 1, the time is given in the DST time zone;\nif it is -1, mktime() should guess based on the date and time.\n\nVariables:\n\ntimezone -- difference in seconds between UTC and local standard time\naltzone -- difference in  seconds between UTC and local DST time\ndaylight -- whether local time should reflect DST\ntzname -- tuple of (standard time zone name, DST time zone name)\n\nFunctions:\n\ntime() -- return current time in seconds since the Epoch as a float\nclock() -- return CPU time since process start as a float\nsleep() -- delay for a number of seconds given as a float\ngmtime() -- convert seconds since Epoch to UTC tuple\nlocaltime() -- convert seconds since Epoch to local time tuple\nasctime() -- convert time tuple to string\nctime() -- convert time in seconds to string\nmktime() -- convert local time tuple to seconds since Epoch\nstrftime() -- convert time tuple to string according to format specification\nstrptime() -- parse string to time tuple according to format specification\ntzset() -- change the local timezone', 'strptime': <built-in function strptime>, 'clock_settime': <built-in function clock_settime>, 'CLOCK_MONOTONIC': 1, 'strftime': <built-in function strftime>, 'time': <built-in function time>, 'CLOCK_PROCESS_CPUTIME_ID': 2, 'monotonic': <built-in function monotonic>, 'gmtime': <built-in function gmtime>, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, 'get_clock_info': <built-in function get_clock_info>, 'clock_getres': <built-in function clock_getres>, 'asctime': <built-in function asctime>, 'CLOCK_THREAD_CPUTIME_ID': 3, 'tzname': ('UTC', 'UTC'), 'CLOCK_MONOTONIC_RAW': 4, 'clock_gettime': <built-in function clock_gettime>, 'clock': <built-in function clock>, 'ctime': <built-in function ctime>, '__spec__': ModuleSpec(name='time', loader=<class '_frozen_importlib.BuiltinImporter'>, origin='built-in'), 'sleep': <built-in function sleep>, 'localtime': <built-in function localtime>, 'struct_time': <class 'time.struct_time'>, 'CLOCK_REALTIME': 0, 'perf_counter': <built-in function perf_counter>, 'tzset': <built-in function tzset>, 'process_time': <built-in function process_time>, 'daylight': 0, '__name__': 'time'}

您可以使用pprint使内容更易于阅读。

>>> import pprint
>>> pprint(vars(time))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'module' object is not callable
>>> pprint.pprint(vars(time))
{'CLOCK_MONOTONIC': 1,
 'CLOCK_MONOTONIC_RAW': 4,
 'CLOCK_PROCESS_CPUTIME_ID': 2,
 'CLOCK_REALTIME': 0,
 'CLOCK_THREAD_CPUTIME_ID': 3,
 '_STRUCT_TM_ITEMS': 11,
 '__doc__': 'This module provides various functions to manipulate time '
            'values.\n'
            '\n'
            'There are two standard representations of time.  One is the '
            'number\n'
            'of seconds since the Epoch, in UTC (a.k.a. GMT).  It may be an '
            'integer\n'
            'or a floating point number (to represent fractions of seconds).\n'
            'The Epoch is system-defined; on Unix, it is generally January '
            '1st, 1970.\n'
            'The actual value can be retrieved by calling gmtime(0).\n'
...

但如果我需要多次这样做,每次都输入pprint和括号会变得很烦人,所以让我定义一个特殊的对象:

>>> pp = type("", (), {"__ror__": lambda self, v: pprint.pprint(v)})()
>>> vars(time) | pp
{'CLOCK_MONOTONIC': 1,
 'CLOCK_MONOTONIC_RAW': 4,
 'CLOCK_PROCESS_CPUTIME_ID': 2,
 'CLOCK_REALTIME': 0,
 'CLOCK_THREAD_CPUTIME_ID': 3,
 '_STRUCT_TM_ITEMS': 11,
 '__doc__': 'This module provides various functions to manipulate time '
            'values.\n'
            '\n'
            'There are two standard representations of time.  One is the '
            'number\n'
            'of seconds since the Epoch, in UTC (a.k.a. GMT).  It may be an '
            'integer\n'
            'or a floating point number (to represent fractions of seconds).\n'
            'The Epoch is system-defined; on Unix, it is generally January '
            '1st, 1970.\n'
            'The actual value can be retrieved by calling gmtime(0).\n'
...

我现在只需要在返回值后添加"| pp"就可以漂亮地打印输出了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接