Python中的对象属性全局处理?

2024-10-02 10:22:05 发布

您现在位置:Python中文网/ 问答频道 /正文

这是我用的Django模型。你知道吗

class Person(models.Model):
    surname = models.CharField(max_length=255, null=True, blank=True)
    first_name = models.CharField(max_length=255, null=True, blank=True)
    middle_names = models.CharField(max_length=255, null=True, blank=True)
    birth_year = WideYear(null=True, blank=True)
    birth_year_uncertain = models.BooleanField()
    death_year = WideYear(null=True, blank=True)
    death_year_uncertain = models.BooleanField()
    flourit_year = WideYear(null=True, blank=True)
    flourit_year_uncertain = models.BooleanField()
    FLOURIT_CHOICES = (
        (u'D', u'Birth and death dates'),
        (u'F', u'Flourit date'),
    )
    use_flourit = models.CharField('Date(s) to use', max_length=2, choices=FLOURIT_CHOICES)
    def __unicode__(self):
        if str(self.birth_year) == 'None':
            self.birth_year = '' 
        if str(self.death_year) == 'None':
            self.death_year = ''
        if str(self.flourit_year) == 'None':
            self.flourit_year = '' 
        if self.use_flourit == u'D':
            return '%s, %s %s (%s - %s)' % (self.surname, self.first_name, self.middle_names, self.birth_year, self.death_year)
        else:
            return '%s, %s %s (fl. %s)' % (self.surname, self.first_name, self.middle_names, self.flourit_year)

模型的unicode方法中的这段代码似乎相当冗长:

if str(self.birth_year) == 'None':
    self.birth_year = '' 
if str(self.death_year) == 'None':
    self.death_year = ''
if str(self.flourit_year) == 'None':
    self.flourit_year = ''

它的目的是阻止unicode方法返回

Murdoch, Rupert (1931 - None)

为了确保方法返回

Murdoch, Rupert (1931 - )

有没有办法以某种方式“glob”该代码位,例如使用通配符以便处理self对象的所有属性?你知道吗

像这样:

if str(self.(*)) == 'None':
   self.$1 = ''

在这里,我只是用正则表达式语法来说明我的意思;很明显,它不适用于python代码。基本上,我们的想法是遍历每个属性,检查它们的str()表示形式是否等于“None”,如果是,则将它们设置为“”。但如果这比设置for循环更简洁的话,那就更好了。你知道吗


Tags: selfnonetrueifmodelsyearnulllength
1条回答
网友
1楼 · 发布于 2024-10-02 10:22:05
for n in dir(self):
  if getattr(self, n) is None:
    setattr(self, n, '')

我使用的是普通的is None习惯用法,假设你使用的那种奇怪的替代方法没有超subtle动机,但这是另一个问题;-)

编辑:如果您使用的框架充满了很深的黑魔法,比如Django,那么完全正常的Python方法可能会突然变得令人担忧,正如OP似乎用类似的模糊编辑所表明的那样。好吧,如果Django的深暗元类不允许这样做(尽管我不能像OP报告的那样重现这个问题),总有其他的选择。特别是,因为这是在一个不应该改变对象的特殊方法(__unicode__)中发生的,所以我推荐一个简单的辅助函数(一个普通的、好用的、独立的模块级函数!)地址:

def b(atr): return atr or u''

使用方法如下:

def __unicode__(self):
  if self.use_flourit == u'D':
    return '%s, %s %s (%s - %s)' % (
        b(self.surname), b(self.first_name), b(self.middle_names),
        b(self.birth_year), b(self.death_year)
    )
  else:
    return '%s, %s %s (fl. %s)' % (
        b(self.surname), b(self.first_name), b(self.middle_names),
        b(self.flourit_year)
    )

请注意,当(A)您想根据需要更改self(在__unicode____str____repr__等转换器中,您不应该这样做)时,我的原始答案是非常好的,并且(B)你所在的类没有使用真正深刻的、黑暗的、烟灰黑魔法(显然Django的models超类正在破坏一些绝对基本的东西,比如dirsetattr、和/或getattr,尽管即使有这个假设,我也无法重现OP报告的特定症状)。你知道吗

相关问题 更多 >

    热门问题