【问题标题】:Can I call the assignment operator of my base class in Python?我可以在 Python 中调用我的基类的赋值运算符吗?
【发布时间】:2014-07-24 17:11:29
【问题描述】:

Django 的ImageField 让我可以使用普通赋值在其中存储一个文件对象。

from urllib import request
from django.db import models
from django.core.files.base import ContentFile

class Customer(models.Model):
    logo = models.ImageField()

customer.logo = ContentFile(request.urlopen(url), 'image.png')

现在我想从ImageField 继承一个自定义字段类型。它将 URL 作为纯字符串而不是文件对象进行分配。在内部,它应该获取图像并将其分配给它的基类,就像上面的手动示例一样。

from django.db import models

class UrlImageField(models.ImageField):
    def __set__(self, instance, value):
        super() = ContentFile(urllib.request.urlopen(value), 'image.png')

因此,我需要在ImageField 基类上调用赋值运算符。我如何在 Python 中做到这一点?

【问题讨论】:

  • 那么你想要的是创建一个获取远程 URL 并将其保存为 ImageField 的字段,对吧?
  • 是什么让你认为 Django 对这个任务做了任何花哨的事情(提示:不是)? image 只是一个名称,它首先引用models.ImageField() 创建的对象,然后引用ContentFile 创建的对象。就是这样。
  • @chepner 那么ContentFile 是如何存储在数据库中的呢?虽然我需要一个ImageField 实例。
  • 我不确定,但即使您没有将任一命令的结果分配给image,它也可能会起作用。我的猜测是 Django 维护了一些使用的隐藏引用。

标签: python django inheritance python-3.x django-models


【解决方案1】:

赋值运算符不能重载。

【讨论】:

  • 那么他们如何使用 Django 的 ImageField 来做到这一点?
  • 你能解释一下你的意思吗?如果我没记错的话,您正在寻找重载 = python 运算符。该运算符是语言固有的,不能重载。
  • @danijar 请注意,x = somethingx.attribute = something 不同。第一个不能被重载,而后者可以通过多种方式。类中的代码也很特殊,因为您可以使用元类对它进行一些控制(至少在 python3.4+ 中),而其他代码则无法控制。
  • 其实=不是运算符;它是由 Python 语法定义的赋值语句的一部分,并且不能比 if 语句更可修改。
  • 该字段可能有与之关联的 getter 和 setter。正如@Bakuriu 提到的,= 属性可以重载。查看此网址以了解更多信息 - stackoverflow.com/questions/2898711/…
【解决方案2】:

您不想(并且不能)重载赋值,但您只想扩展ImageField 描述符。 描述符在Descriptor HowTo Guide 中有深入解释。您还应该看看:Understanding __get__ and __set__ and Python descriptors

本质是它们定义了控制属性访问__set____get__ 方法。这些方法只是普通方法,因此您必须像普通方法一样扩展它们:

from django.db import models

class UrlImageField(models.ImageField):
    def __set__(self, instance, value):
        super().__set__(instance, ContentFile(urllib.request.urlopen(value), 'image.png'))

【讨论】:

  • 非常感谢,我想我现在明白了。但是,它仍然是doesn't quite work。你有什么想法吗?
猜你喜欢
  • 2019-04-16
  • 1970-01-01
  • 2021-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-10
  • 2011-03-13
  • 1970-01-01
相关资源
最近更新 更多