【问题标题】:Can an operator be overloaded as a class method in python?可以将运算符重载为python中的类方法吗?
【发布时间】:2012-06-02 03:29:54
【问题描述】:

为了使扩展看起来非常干净,我尝试在 python 中将“>>”运算符实现为类方法。我不知道该怎么做。我不想创建一个实例,因为我实际上是在对类本身进行操作。

>>> class C:
...     @classmethod
...     def __rshift__(cls, other):
...         print("%s got %s" % (cls, other))
...
>>> C.__rshift__("input")
__main__.C got input
>>> C() >> "input"
__main__.C got input
>>> C >> "input"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for >>: 'classobj' and 'str'

背景资料:

我正在尝试在 peewee ORM(类似于 Django)中实现视图。 Peewee 允许您将数据库表及其关系定义为类,如下所示:

class Track(Model):
    title = CharField()
    artist = ForeignKeyField(Artist)

class Artist(Model):
    name = CharField(unique = True)
    location = ForeignKeyField(Location)

class Location(Model):
    state = CharField(size = 2)
    city = CharField()

注意:为了清楚起见,顺序颠倒了。

我正在尝试通过视图的实现来扩展它。最困难的部分之一是设置一个干净的方式来指示连接。到目前为止,我已经实现了以下内容:

class Song(View):
    title = Track.title
    artist = Track.artist >> "name"
    state = Track.artist >> "location" >> "state"

这没关系,但我真的很想消除“。”进一步简化:

class Song(View):
    title = Track >> "title"
    artist = Track >> "artist" >> "name"
    state = Track >> "artist" >> "location" >> "state"

您更愿意使用哪个?还是两者兼有?

作为旁注,任何人都可以想出一种表示向后加入的好方法吗?像下面这样的东西对我来说有点尴尬:

class LocWithSong(View):
    state = Location >> "state"
    title = Location >> Track.title

【问题讨论】:

  • 这里是peewee的作者,我喜欢你提出的API!随意在 GitHub 上分叉并回馈您的更改:github.com/coleifer/peewee 或加入邮件列表 groups.google.com/group/peewee-orm

标签: python class operator-overloading peewee


【解决方案1】:

定义方法on the metaclass

class MC(type):
  def __rshift__(self, other):
    return something(self, other)

class C(object):
  __metaclass__ = MC

print C >> None

【讨论】:

  • 谢谢,我从来没想过。搜索起来非常困难,我看到的所有内容都提取了与标准重载无关的信息。感谢您的及时回复。
  • 请注意,在 Python3 中,语法有点不同:class C(metaclass=MC)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-18
  • 1970-01-01
  • 2019-04-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多