混淆 Python 设置两次添加相同的对象
Confused with Python sets adding same object twice
如果我将整数添加到 Python 集合对象两次,Python 只会添加一次。
a = set()
a.add(5)
a.add(5)
print(a)
>> {5}
但是,在我的应用程序中,我试图将协程添加到集合中,因为我找不到更好的方法来跟踪 event_loop 中已经有哪些协程。我对以下行为感到惊讶:
async def foo(something):
await asyncio.sleep(1)
print(something)
a = set()
coro_obj = foo("hi")
a.add(coro_obj)
coro_obj = foo("hi")
a.add(coro_obj)
print(a)
{<coroutine object foo at 0x7f36f8c52888>, <coroutine object foo at 0x7f36f8c52360>}
我不太确定我在这里做了什么。如果协程对象不可哈希,它就不会被添加到集合中,我的想法是否正确?所以它是可哈希的,对吗?
那么如果它是可散列的,为什么我们得到两个具有相同 method/argument 的不同散列?
集合使用散列来比较对象,因此如果两个对象的 __ hash __()
方法将 return 值相同,则两个对象将被视为相等。在您的示例中,它将是这样的:
a = set()
coro_obj = foo("hi")
a.add(coro_obj.__hash__())
coro_obj = foo("hi")
a.add(coro_obj.__hash__())
print(a)
{-9223363267847141772, 8769007586508}
如你所见,两个对象的哈希是不同的,这都取决于内部协程 __ hash __ 方法的实现
ADDITION:并且 obj1.__ eq__(obj2) 也应该是 True
您可以使用字典来存储函数和参数集。
# dict to store functions
foo_dict = {}
# function that adds functions and sets of args to dict
d_add = lambda d, f, args : d[foo].add(args) if f in d else d.update({f: {args}} )
# function that makes a list of coroutine objects from this dict
d_bake = lambda d:[f(*args) for f, args_list in d.items() for args in args_list]
结果:
d_add(foo_dict, foo, ("hi",))
d_add(foo_dict, foo, ("hi", "bye"))
d_add(foo_dict, foo, ("hi",))
d_add(foo_dict, foo, ("hi",))
print(foo_dict)
#{<function foo at 0x7fefc0be1268>: {('hi',), ('hi', 'bye')}}
print(d_bake(foo_dict))
#[<coroutine object foo at 0x7fefc0f39f68>, <coroutine object foo at 0x7fefc0bec048>]
如果我将整数添加到 Python 集合对象两次,Python 只会添加一次。
a = set()
a.add(5)
a.add(5)
print(a)
>> {5}
但是,在我的应用程序中,我试图将协程添加到集合中,因为我找不到更好的方法来跟踪 event_loop 中已经有哪些协程。我对以下行为感到惊讶:
async def foo(something):
await asyncio.sleep(1)
print(something)
a = set()
coro_obj = foo("hi")
a.add(coro_obj)
coro_obj = foo("hi")
a.add(coro_obj)
print(a)
{<coroutine object foo at 0x7f36f8c52888>, <coroutine object foo at 0x7f36f8c52360>}
我不太确定我在这里做了什么。如果协程对象不可哈希,它就不会被添加到集合中,我的想法是否正确?所以它是可哈希的,对吗?
那么如果它是可散列的,为什么我们得到两个具有相同 method/argument 的不同散列?
集合使用散列来比较对象,因此如果两个对象的 __ hash __()
方法将 return 值相同,则两个对象将被视为相等。在您的示例中,它将是这样的:
a = set()
coro_obj = foo("hi")
a.add(coro_obj.__hash__())
coro_obj = foo("hi")
a.add(coro_obj.__hash__())
print(a)
{-9223363267847141772, 8769007586508}
如你所见,两个对象的哈希是不同的,这都取决于内部协程 __ hash __ 方法的实现
ADDITION:并且 obj1.__ eq__(obj2) 也应该是 True
您可以使用字典来存储函数和参数集。
# dict to store functions
foo_dict = {}
# function that adds functions and sets of args to dict
d_add = lambda d, f, args : d[foo].add(args) if f in d else d.update({f: {args}} )
# function that makes a list of coroutine objects from this dict
d_bake = lambda d:[f(*args) for f, args_list in d.items() for args in args_list]
结果:
d_add(foo_dict, foo, ("hi",))
d_add(foo_dict, foo, ("hi", "bye"))
d_add(foo_dict, foo, ("hi",))
d_add(foo_dict, foo, ("hi",))
print(foo_dict)
#{<function foo at 0x7fefc0be1268>: {('hi',), ('hi', 'bye')}}
print(d_bake(foo_dict))
#[<coroutine object foo at 0x7fefc0f39f68>, <coroutine object foo at 0x7fefc0bec048>]