python中的类型转换类:如何?

Tho*_*hew 1 python oop class

在这里,我试图将社交媒体配置文件模拟为"个人资料"类,其中您有姓名,一群朋友,以及添加和删除朋友的能力.我想制作一种方法,在调用时,将按字母顺序打印朋友列表.

问题:我得到一个警告,我无法对不合格的类型进行排序.Python将我的实例变量视为"配置文件对象",而不是我可以排序和打印的列表.

这是我的代码:

class Profile(object):
    """
    Represent a person's social profile

    Argument:
    name (string): a person's name - assumed to uniquely identify a person

    Attributes:
    name (string): a person's name - assumed to uniquely identify a person
    statuses (list): a list containing a person's statuses - initialized to []
    friends (set): set of friends for the given person.
                   it is the set of profile objects representing these friends.
    """

    def __init__(self, name):
        self.name = name
        self.friends = set()
        self.statuses = []

    def __str__(self):
        return self.name + " is " + self.get_last_status()

    def update_status(self, status):
        self.statuses.append(status)
        return self

    def get_last_status(self):
        if len(self.statuses) == 0:
            return "None"
        else:
            return self.statuses[-1]

    def add_friend(self, friend_profile):
        self.friends.add(friend_profile)
        friend_profile.friends.add(self)
        return self

    def get_friends(self):
        if len(self.friends) == 0:
            return "None"
        else:
            friends_lst = list(self.friends)
            return sorted(friends_lst)
Run Code Online (Sandbox Code Playgroud)

在我填写朋友列表(从测试模块)并调用get_friends方法后,python告诉我:

 File "/home/tjm/Documents/CS021/social.py", line 84, in get_friends
    return sorted(friends_lst)
TypeError: unorderable types: Profile() < Profile()
Run Code Online (Sandbox Code Playgroud)

为什么我不能简单地将对象强制转换为以列表形式获取它?我应该做什么,以便get_friends将返回按字母顺序排序的朋友列表?

ozg*_*gur 6

排序算法查找存在__eq__,__ne__,__lt__,__le__,__gt__,__ge__方法类的定义比较,从他们创建的实例.您需要覆盖这些方法以调整其行为.

出于性能原因,我建议您为类定义一些integer属性,id并将其用于比较,而不是name具有字符串比较开销.

class Profile(object):
    def __eq__(self, profile):
        return self.id == profile.id # I made it up the id property.

    def __lt__(self, profile):
        return self.id < profile.id

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

    ...
Run Code Online (Sandbox Code Playgroud)

或者,key如果您不想打扰自己覆盖这些方法,则可以将函数传递给排序算法:

>>> friend_list = [<Profile: id=120>, <Profile: id=121>, <Profile: id=115>]
>>> friend_list.sort(key=lambda p: p.id, reverse=True)
Run Code Online (Sandbox Code Playgroud)

使用operator.attrgetter;

>>> import operator
>>> new_friend_list = sorted(friend_list, key=operator.attrgetter('id')) 
Run Code Online (Sandbox Code Playgroud)

  • 请注意,此解决方案不起作用,因为现在实例不再可以清除,因此以下行`self.friends.add(friend_profile); friend_profile.friends.add(self)`将引发错误. (2认同)