Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用自定义哈希函数创建namedtuple_Python_Inheritance_Overriding_Tuples - Fatal编程技术网

Python 使用自定义哈希函数创建namedtuple

Python 使用自定义哈希函数创建namedtuple,python,inheritance,overriding,tuples,Python,Inheritance,Overriding,Tuples,假设我有一个名为tuple的,如下所示: FooTuple = namedtuple("FooTuple", "item1, item2") 我希望以下函数用于散列: foo_hash(self): return hash(self.item1) * (self.item2) 我之所以希望这样做,是因为我希望item1和item2的顺序不相关(我将对比较运算符执行相同的操作)。我想到了两种方法。第一个是: FooTuple.__hash__ = foo_hash 这是可行的,但感觉

假设我有一个名为tuple的
,如下所示:

FooTuple = namedtuple("FooTuple", "item1, item2")
我希望以下函数用于散列:

foo_hash(self):
    return hash(self.item1) * (self.item2)
我之所以希望这样做,是因为我希望
item1
item2
的顺序不相关(我将对比较运算符执行相同的操作)。我想到了两种方法。第一个是:

FooTuple.__hash__ = foo_hash
这是可行的,但感觉被黑客攻击了。因此,我尝试子类化
FooTuple

class EnhancedFooTuple(FooTuple):
    def __init__(self, item1, item2):
        FooTuple.__init__(self, item1, item2)

    # custom hash function here
但我明白了:

DeprecationWarning: object.__init__() takes no parameters

那么,我能做什么?或者这完全是一个坏主意,我应该从头开始编写自己的类吗?

我认为您的代码有问题(我猜您创建了一个同名的元组实例,所以
fooTuple
现在是一个元组,而不是元组类),因为这样子类化命名的元组应该可以工作。无论如何,您不需要重新定义构造函数。您只需添加哈希函数即可:

In [1]: from collections import namedtuple

In [2]: Foo = namedtuple('Foo', ['item1', 'item2'], verbose=False)

In [3]: class ExtendedFoo(Foo):
   ...:     def __hash__(self):
   ...:         return hash(self.item1) * hash(self.item2)
   ...: 

In [4]: foo = ExtendedFoo(1, 2)

In [5]: hash(foo)
Out[5]: 2

从Python3.6.1开始,可以通过
键入.NamedTuple
类更清晰地实现这一点(只要您对类型提示没有问题):

具有自定义函数的可用于存储到和中

例如:

class Point(namedtuple('Point', ['label', 'lat', 'lng'])):
    def __eq__(self, other):
        return self.label == other.label

    def __hash__(self):
        return hash(self.label)

    def __str__(self):
        return ", ".join([str(self.lat), str(self.lng)])
覆盖
\uuuuu eq\uuuuuu
\uuuuu hash\uuuuu
允许将业务分组到
集合中,确保集合中的每个业务线都是唯一的:

walgreens = Point(label='Drugstore', lat = 37.78735890, lng = -122.40822700)
mcdonalds = Point(label='Restaurant', lat = 37.78735890, lng = -122.40822700)
pizza_hut = Point(label='Restaurant', lat = 37.78735881, lng = -122.40822713)

businesses = [walgreens, mcdonalds, pizza_hut]
businesses_by_line = set(businesses)

assert len(business) == 3
assert len(businesses_by_line) == 2

请注意,
repr(foo)
仍将谈论
foo
。这可以做得更好,因为
类Foo(namedtuple('Foo',['item1','item2',verbose=False)):
注意@Sven的答案
walgreens = Point(label='Drugstore', lat = 37.78735890, lng = -122.40822700)
mcdonalds = Point(label='Restaurant', lat = 37.78735890, lng = -122.40822700)
pizza_hut = Point(label='Restaurant', lat = 37.78735881, lng = -122.40822713)

businesses = [walgreens, mcdonalds, pizza_hut]
businesses_by_line = set(businesses)

assert len(business) == 3
assert len(businesses_by_line) == 2