在 python 中强制转换 类:怎么样?

typecast classes in python: how?

在这里,我试图将社交媒体资料模拟为 class "Profile",其中您有姓名、一群朋友以及添加和删除朋友的能力。我想做一个方法,当调用时,将按字母顺序打印朋友列表。

问题:我收到一条警告,提示我无法对无法排序的类型进行排序。 Python 将我的实例变量视为 "Profile object",而不是我可以排序和打印的列表。

这是我的代码:

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)

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

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

为什么我不能简单地将对象类型转换为列表形式?我应该怎么做才能让 get_friends 成为 return 按字母顺序排序的朋友列表?

排序算法查找 __eq____ne____lt____le____gt____ge__ class 定义来比较从它们创建的实例。您需要重写这些方法以调整它们的行为。

出于性能原因,我建议您为 class 定义一些 integer 属性,例如 id,并将其用于比较而不是 [=21] =] 有字符串比较开销。

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)

    ...

或者,如果您不想打扰自己重写这些方法,您可以传递一个 key 函数来排序算法:

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

使用operator.attrgetter;

>>> import operator
>>> new_friend_list = sorted(friend_list, key=operator.attrgetter('id')) 

我想我会尝试一下。首先,这是代码:

from collections import namedtuple

class Profile(namedtuple("Profile", "name")):
    def __init__(self, name):
        # don't set self.name, it's already set!
        self.friends = set({})
        self.statuses = list([])

    # ... and all the rest the same.  Only the base class changes.

我们在这里所做的是用元组的形状创建一个class。因此,它是可排序的、可散列的以及所有的东西。您甚至可以放弃 __str__() 方法,namedtuple 提供了一个不错的方法。