繁体   English   中英

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

[英]Python - Setting an attribute to the value of a method - cleanest way?

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

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

我目前正在使用lambda解决这个问题。 在寻找答案时,似乎解决这个问题的“正确”方法可能是使用types.MethodType但我似乎无法types.MethodType它。 是的,我已经阅读过Raymond出色的指南,但我显然遗漏了一些东西..这是我目前对那些感兴趣的人的解决方案..

# Defined Elsewhere
class User:
    name = models.CharField(max_length=32)
class Company(models.Model):
    users =  models.ManyToManyField(User, related_name="companies", blank=True, null=True)

# Here is the meat of this..
class UserProfile(models.Model):
    """This defines Users"""
    user = models.OneToOneField(User)

    def get_company(self):
        try:
            companies = self.user.companies.all()[0]
        except (AttributeError, IndexError):
            return None

User.company = property(lambda u: UserProfile.objects.get_or_create(user=u)[0].get_company())

现在这有效.. 但是有更好的方法 - 我不是疯狂的lambdas?

我不太确定我是否正确理解你的目标是什么,但从我认为我理解的情况来看,似乎没有必要在这里使用描述符做任何疯狂的事情,更不用说types.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())

编辑:如果无法触摸User类,则可以创建添加所需属性的派生类:

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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM