为什么我不能使用
我在网上看到使用__getattr__
和Django模型的人的例子,但是每当我尝试我会得到错误。 (Django 1.2.3)
当我在普通对象上使用__getattr__
时,我没有任何问题。 例如:
class Post(object):
def __getattr__(self, name):
return 42
工作得很好...
>>> from blog.models import Post
>>> p = Post()
>>> p.random
42
现在,当我尝试使用Django模型时:
from django.db import models
class Post(models.Model):
def __getattr__(self, name):
return 42
并在口译员身上进行测试:
>>> from blog.models import Post
>>> p = Post()
ERROR: An unexpected error occurred while tokenizing input The
跟踪回溯可能已损坏或无效错误消息是:('EOF in multi-line statement',(6,0))
-------------------------------------------------- ------------------------- TypeError
回溯(最近一次通话最后)
/ Users / josh / project / in()
/Users/josh/project/lib/python2.6/site-packages/django/db/models/base.pyc in init (self,* args,** kwargs)338 if kwargs:339 raise TypeError(“'%s '是这个函数”%kwargs.keys()[0])无效的关键字参数- > 340 signals.post_init.send(发件人=自类 ,实例=自我)341 342 DEF 再版 (个体):
/Users/josh/project/lib/python2.6/site-packages/django/dispatch/dispatcher.pyc in send(self,sender,** named)160 161 for self._live_receivers(_make_id(sender)): - > 162 response = receive(signal = self,sender = sender,** named)163 responses.append((receiver,response))164返回响应
/Users/josh/project/python2.6/site-packages/photologue/models.pyc in add_methods(sender,instance,signal,* args,** kwargs)728“”“729 if hasattr(instance,'add_accessor_methods') : - > 730 instance.add_accessor_methods()731 732#将add_accessor_methods函数连接到post_init信号
TypeError:'int'对象不可调用
有人可以解释发生了什么吗?
编辑:我可能已经太抽象的例子,这里是一些代码,更接近我实际上会在网站上使用:
class Post(models.Model):
title = models.CharField(max_length=255)
slug = models.SlugField()
date_published = models.DateTimeField()
content = RichTextField('Content', blank=True, null=True)
# Etc...
Class CuratedPost(models.Model):
post = models.ForeignKey('Post')
position = models.PositiveSmallIntegerField()
def __getattr__(self, name):
''' If the user tries to access a property of the CuratedPost, return the property of the Post instead... '''
return self.post.name
# Etc...
虽然我可以为Post类的每个属性创建一个属性,但这会导致很多代码重复。 此外,这意味着,无论何时我添加或编辑Post类的属性,我都必须记住对CuratedPost类进行相同的更改,这看起来像是代码rot的配方。
你必须小心使用__getattr__。 只拦截你知道的东西,让基类处理你不知道的东西。
第一步是,你可以使用一个属性吗? 如果你想要一个返回42的“随机”属性,那么这更安全:
class Post(...):
@property
def random(self):
return 42
如果你想要“random_ *”(比如“random_1”,“random_34”等)做一些事情,那么你必须使用__getattr__这样的:
class Post(...):
def __getattr__(self, name):
if name.startswith("random_"):
return name[7:]
return super(Post, self).__getattr__(name)
Django在模型首次初始化时(即,加载shell)发送特定的信号 - 通过使得__getattr
调用总是返回一个整数,您已经以Django信号不期望的方式修改了代码(以及因此,他们正在打破)。
如果你想这样做,也许试试这样:
def __getattr__(self, attr):
if hasattr(self, attr):
return super(MyModel, self).__getattr__(attr)
return 42
链接地址: http://www.djcxy.com/p/54165.html
上一篇: Why can't I use
下一篇: Where should I put helper functions for scripts that utilize a common module?