gpt4 book ai didi

python - `__getitem___`的反转

转载 作者:行者123 更新时间:2023-12-01 05:01:37 24 4
gpt4 key购买 nike

d[x] 其中 d 是一个字典,调用 d.__getitem__(x)。有没有办法创建一个类F,以便y=F(X); d[y] 会调用 F 中的某个方法:y.someMethod(d)?

背景:我正在尝试使用“别名”键创建一个字典,这样如果我有 d[a]=42,则 d[alias_of_a]也会返回 42。对于自定义 __getitem__ 来说,这非常简单,例如:

class oneOf(object):
def __init__(self, *keys):
self.keys = keys

class myDict(dict):
def __getitem__(self, item):
if isinstance(item, oneOf):
for k in item.keys:
if k in self:
return self[k]
return dict.__getitem__(self, item)


a = myDict({
'Alpha': 1,
'B': 2,
})

print a[oneOf('A', 'Alpha')]
print a[oneOf('B', 'Bravo')]

但是,我想知道是否可以在不覆盖dict的情况下实现:

a = {
'Alpha': 1,
'B': 2,
}

print a[???('A', 'Alpha')]
print a[???('B', 'Bravo')]

如果这是不可能的,如何让它以相反的方式工作:

a = {
???('A', 'Alpha'): 1,
???('B', 'Bravo'): 2,
}

print a['A']
print a['Bravo']

对我来说重要的是我想避免扩展 dict

最佳答案

这个用例是不可能的:

a = {
'Alpha': 1,
'B': 2,
}

a[???('A', 'Alpha')]
a[???('B', 'Bravo')]

这是因为dict首先会散列该对象。为了强制发生冲突(这将允许优先相等),哈希值需要匹配。但是???('A', 'Alpha')只能散列到 'A' 中的一个'Alpha' ,如果它做出了错误的选择,它就失败了。

另一个用例也应用了类似的推论:

a = {
???('A', 'Alpha'): 1,
???('B', 'Bravo'): 2,
}

a['A']
a['Bravo']

a['A']将使用不同的哈希值来查找 a['Alpha'] ,再次???('A', 'Alpha')需要有两个哈希值,这是不可能的。

您需要键和值的配合才能使其发挥作用。

<小时/>

理论上你可以使用inspect.getouterframes__hash__方法来检查字典的值,但这仅在字典具有 Python 框架时才有效。如果你的意图是猴子修补一个函数,该函数有点做你想要的但不完全,这可能(只是)工作(大概)。

import inspect

class VeryHackyAnyOfHack:
def __init__(self, variable_name_hack, *args):
self.variable_name_hack = variable_name_hack
self.equal_to = args

def __eq__(self, other):
return other in self.equal_to

def __hash__(self):
outer_frame = inspect.getouterframes(inspect.currentframe())[1]

assumed_target_dict = outer_frame[0].f_locals[self.variable_name_hack]

for item in self.equal_to:
if item in assumed_target_dict:
return hash(item)

# Failure
return hash(item[0])

使用方式如下:

import random

def check_thing_agains_dict(item):
if random.choice([True, False]):
internal_dict = {"red": "password123"}
else:
internal_dict = {"blue": "password123"}

return internal_dict[item]

myhack = VeryHackyAnyOfHack('internal_dict', "red", "blue")
check_thing_agains_dict(myhack)
#>>> 'password123'

同样,您必须这样做的事实意味着在实践中这是不可能的。它也是一种语言扩展,因此不可移植。

关于python - `__getitem___`的反转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25973221/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com