将对象的字符串表示形式与列表中每个对象的字符串表示形式进行比较

时间:2012-10-20 21:34:56

标签: python oop

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

下面的示例代码(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)

(因为它会失败,因为它会比较对象而不是它们所代表的字符串。)

2 个答案:

答案 0 :(得分:1)

if str(test_url) not in [str(url) for url in list_of_urls]

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

答案 1 :(得分: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”的字符串属性。但是,如果比较其他对象,则会失败。