示例:社交关系

微博、twitter 以及类似的社交网站都允许用户通过加关注或者加好友的方式,构建一种社交关系:这些网站上的每个用户都可以关注其他用户,也可以被其他用户关注。通过正在关注名单(following list),用户可以查看自己正在关注的用户及其人数;而通过关注者名单(follower llist),用户可以查看有哪些人正在关注自己,以及有多少人正在关注自己。

代码清单 5-5 展示了一个使用集合来记录社交关系的方法:

  • 程序为每个用户维持两个集合,一个集合储存用户的正在关注名单,而另一个集合则储存用户的关注者名单。

  • 当一个用户(关注者)关注另一个用户(被关注者)的时候,程序会将被关注者添加到关注者的正在关注名单里面,并将关注者添加到被关注者的关注者名单里面。

  • 当关注者取消对被关注者的关注时,程序会将被关注者从关注者的正在关注名单中移除,并将关注者从被关注者的关注者名单中移除。


代码清单 5-5 使用集合实现社交关系:/set/relationship.py

  1. def following_key(user):
  2. return user + "::following"
  3.  
  4. def follower_key(user):
  5. return user + "::follower"
  6.  
  7. class Relationship:
  8.  
  9. def __init__(self, client, user):
  10. self.client = client
  11. self.user = user
  12.  
  13. def follow(self, target):
  14. """
  15. 关注目标用户。
  16. """
  17. # 把 target 添加到当前用户的正在关注集合里面
  18. user_following_set = following_key(self.user)
  19. self.client.sadd(user_following_set, target)
  20. # 把当前用户添加到 target 的关注者集合里面
  21. target_follower_set = follower_key(target)
  22. self.client.sadd(target_follower_set, self.user)
  23.  
  24. def unfollow(self, target):
  25. """
  26. 取消对目标用户的关注。
  27. """
  28. # 从当前用户的正在关注集合中移除 target
  29. user_following_set = following_key(self.user)
  30. self.client.srem(user_following_set, target)
  31. # 从 target 的关注者集合中移除当前用户
  32. target_follower_set = follower_key(target)
  33. self.client.srem(target_follower_set, self.user)
  34.  
  35. def is_following(self, target):
  36. """
  37. 检查当前用户是否正在关注目标用户,
  38. 是的话返回 True ,否则返回 False 。
  39. """
  40. # 如果 target 存在于当前用户的正在关注集合中
  41. # 那么说明当前用户正在关注 target
  42. user_following_set = following_key(self.user)
  43. return self.client.sismember(user_following_set, target)
  44.  
  45. def get_all_following(self):
  46. """
  47. 返回当前用户正在关注的所有人。
  48. """
  49. user_following_set = following_key(self.user)
  50. return self.client.smembers(user_following_set)
  51.  
  52. def get_all_follower(self):
  53. """
  54. 返回当前用户的所有关注者。
  55. """
  56. user_follower_set = follower_key(self.user)
  57. return self.client.smembers(user_follower_set)
  58.  
  59. def count_following(self):
  60. """
  61. 返回当前用户正在关注的人数。
  62. """
  63. user_following_set = following_key(self.user)
  64. return self.client.scard(user_following_set)
  65.  
  66. def count_follower(self):
  67. """
  68. 返回当前用户的关注者人数。
  69. """
  70. user_follower_set = follower_key(self.user)
  71. return self.client.scard(user_follower_set)

以下代码展示了社交关系程序的基本使用方法:

  1. >>> from redis import Redis
  2. >>> from relationship import Relationship
  3. >>> client = Redis(decode_responses=True)
  4. >>> peter = Relationship(client, 'peter') # 这个对象记录的是 peter 的社交关系
  5. >>> peter.follow('jack') # 关注一些人
  6. >>> peter.follow('tom')
  7. >>> peter.follow('mary')
  8. >>> peter.get_all_following() # 获取目前正在关注的所有人
  9. set(['mary', 'jack', 'tom'])
  10. >>> peter.count_following() # 统计目前正在关注的人数
  11. 3
  12. >>> jack = Relationship(client, 'jack') # 这个对象记录的是 jack 的社交关系
  13. >>> jack.get_all_follower() # peter 前面关注了 jack ,所以他是 jack 的关注者
  14. set(['peter'])
  15. >>> jack.count_follower() # jack 目前只有一个关注者
  16. 1

图 5-10 展示了以上代码创建的各个集合。


图 5-10 社交关系集合示例_images/IMAGE_RELATIONSHIP_EXAMPLE.png