0

是否有一种简单的方法可以将对象的字符串表示形式与列表中的每个对象进行比较?

下面的示例代码(Python 2.7)按预期工作,但我认为在 Python 中有更好的方法来做到这一点!

class url(object):
    def __init__(self, address):
       self.address = address

    def __str__(self):
        return self.address

list_of_urls = [url('http://www.example.foo'), url('http://www.example.bar')]
test_url = url('http://www.example.foobar')

test_url_listed = False
for link in list_of_urls:
    if str(test_url) == str(link):
        test_url_listed = True

if not test_url_listed:
    list_of_urls.append(test_url)

是否可以使其在结构上更接近以下内容?

if test_url not in list_of_urls:
    list_of_urls.append(test_url)

(事实上​​,这失败了,因为它比较的是对象而不是它们所代表的字符串。)

4

2 回答 2

1

最快的方法是实现该__cmp__方法。

class url(object):
    def __init__(self, address):
       self.address = address

    def __str__(self):
        return self.address

    def __cmp__(self, other):
        return cmp(self.address, other.address)


list_of_urls = [url('http://www.example.foo'), url('http://www.example.bar')]
test_url = url('http://www.example.foobar')

这在:

if test_url not in list_of_urls:
    print("Not in")

打印“不在”。

或者,您可以使用“丰富”的比较,但这需要更多的努力。类total_ordering方法可以提供帮助。

from functools import total_ordering

@total_ordering
class url(object):
    def __init__(self, address):
       self.address = address

    def __str__(self):
        return self.address

    def __eq__(self, other):
        return self.address == other.address

    def __lt__(self, other):
        return self.address < other.address

这使得所有比较都使用名为“address”的字符串属性。但是,如果您比较其他对象,这将失败。

于 2012-10-20T21:56:01.170 回答
1
if str(test_url) not in [str(url) for url in list_of_urls]

或者更好的是,在 url 类上实现__cmp__和/或__eq__+ 。__ne__(可能还有__hash__。)然后您可以创建一个seturl,它会自动确保没有重复的 url。

于 2012-10-20T21:36:34.883 回答