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

sam*_*per 1 python oop django-models

这是我正在使用的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)
Run Code Online (Sandbox Code Playgroud)

来自模型的__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 = ''
Run Code Online (Sandbox Code Playgroud)

它的目的是阻止__unicode__方法返回类似的东西

默多克,鲁珀特(1931年 - 无)

并确保该方法返回类似的东西

默多克,鲁珀特(1931 - )

有没有办法以某种方式"填充"那段代码,例如使用通配符以便处理自身对象的所有属性?

像这样的东西:

if str(self.(*)) == 'None':
   self.$1 = ''
Run Code Online (Sandbox Code Playgroud)

在这里,我刚刚使用正则表达式语法来说明我的意思; 显然,它不是python代码.本质上,我们的想法是循环遍历每个属性,检查它们的str()表示是否等于'None',如果是,则将它们设置为''.但是,如果能够通过设置for循环来更简洁地完成它,那将是很好的.

Ale*_*lli 5

for n in dir(self):
  if getattr(self, n) is None:
    setattr(self, n, '')
Run Code Online (Sandbox Code Playgroud)

我正在使用正常的is None习语,假设你正在使用的那个奇怪的替代方案没有超级动机,但这是一个单独的问题;-)

编辑:如果你正在使用一个充满非常深刻的黑魔法的框架,比如Django,完全正常的Python方法突然可能会变得充满 - 因为OP似乎已经用类似的黑暗编辑表示.好吧,如果Django的黑暗深层元素不能让它工作(尽管我不能像OP报告的那样重现这个问题),总有其他选择.特别是,因为这是在一个不应该改变对象(__unicode__特别是)的特殊方法中发生的,所以我推荐一个简单的辅助函数(一个简单的旧的独立模块级函数!):

def b(atr): return atr or u''
Run Code Online (Sandbox Code Playgroud)

使用如下:

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)
    )
Run Code Online (Sandbox Code Playgroud)

请注意,我原来的答复是完全正常时(A)你想改变self的需要(在转换器等__unicode__,__str__,__repr__,...,你不应该!),和(b)你在那并不是一个类T选用非常深,暗,烟尘黑魔法(显然是Django的型号超是打破一些诸如绝对重要dir,setattr和/或getattr-但即使与假设我只是无法重现具体的症状由OP有些报).