Python-将属性设置为方法的值-最干净的方式?

Python-将属性设置为方法的值-最干净的方式?,python,django,Python,Django,我需要一个方便的属性来执行以下操作: from django.contrib.auth.models import User user = User.objects.get(id=2) user.company <Company: Big Company L.L.C> 现在这个办法奏效了但是有没有更好的方法-我不喜欢lambdas???我不太确定我是否正确理解了您的目标,但是从我认为我理解的情况来看,这里似乎没有必要对描述符做任何疯狂的事情,更不用说类型了。MethodType。一

我需要一个方便的属性来执行以下操作:

from django.contrib.auth.models import User
user = User.objects.get(id=2)
user.company
<Company: Big Company L.L.C>

现在这个办法奏效了但是有没有更好的方法-我不喜欢lambdas???

我不太确定我是否正确理解了您的目标,但是从我认为我理解的情况来看,这里似乎没有必要对描述符做任何疯狂的事情,更不用说
类型了。MethodType
。一个简单的属性就可以了,如果您不喜欢lambda,可以使用一个用
@property
修饰的普通函数:

class User:
    name = models.CharField(max_length=32)
    @property
    def company(self):
        return UserProfile.objects.get_or_create(user=self)[0].get_company())
编辑:如果无法触摸
用户
类,则可以创建一个派生类,添加所需的属性:

class MyUser(User):
    @property
    def company(self):
        return UserProfile.objects.get_or_create(user=self)[0].get_company())

基于@SvenMarnach的答案,您仍然可以在不使用lambda的情况下完成相同的任务。尽管您仍然需要使用猴子补丁:

def _get_user_company(user):
    return UserProfile.objects.get_or_create(user=user)[0].get_company()
User.company = property(_get_user_company)

您不能向Django库中的类添加方法。@InReadia:
User
似乎不是Django库中的类。(如果您不能更改某个类,只需从该类派生,而不是对其进行monkey修补)。子类化并没有真正的帮助,因为模块的函数不会返回您的子类。@Inedia:我明白了。在这种情况下,猴子补丁是唯一的选择。lambda会导致任何问题吗?如果没有,你有一个你正在尝试做的工作的实现——为什么要让事情变得困难呢?不,它在工作,但我对它们不太满意。我总是用反模式的眼光看待它们……在Python2.x中,除了AttributeError、indexer:之外,还要小心
。它将只捕获
属性错误
,并将捕获的异常分配给
索引错误
。使用
除了(AttributeError,indexer):
代替。是的-很好,我在代码中修复了它@rh0dium:我尝试搜索惯用的monkeypatching,发现GvR发布了一个2008年的邮件列表,其中包含一些代码,这些代码只是为类分配了一个常规函数。显然这不是权威,但它是一个数据点,支持保持简单。嗯。。我想get_或create会返回一个元组。。??。。。对不起,你说得对。我通常使用类似于
obj,created=MyModel.objects.get\u或\u create()
的东西,因此数组选择器会让我想起
filter
def _get_user_company(user):
    return UserProfile.objects.get_or_create(user=user)[0].get_company()
User.company = property(_get_user_company)