我有一个简单的场景。我将一个kwarg prop_name
和prop_func
传递到我的类init中,我希望将其转换为以下属性:
class A:
def __init__(self, *args, prop_name=None, prop_func=None, **kwargs):
if prop_name is not None and prop_func is not None:
setattr(self, prop_name, property(prop_func))
super().__init__(*args, **kwargs)
为什么我不能这样做:
a = A(prop_name='some_name', prop_func=lambda _: 1)
print(a.some_name)
结果是:
>>> <property object at 0x7feb3f27cf98>
然而,这有效:
class A:
some_name = property(lambda _: 1)
a = A()
print(a.some_name)
>>> 1
编辑:可能的解决办法,以获得相同的行为。如果有任何实际差异,请更正。
class A:
def __init__(self, *args, prop_name=None, prop_func=None, **kwargs):
self._prop_name = prop_name
self._prop_func = prop_func
def __getattr__(self, item):
if item == self._prop_name:
return self._prop_func(self) # this solution does not accept arguments
super().__getattr__(self, item)
a = A(prop_name='some_name', prop_func=lambda _: 1)
print(a.some_name)
>>> 1
编辑2:解释为什么需要此行为解决方案。
对于django视图,此行为应该在Mixin
中发生。目标是能够动态创建相关对象之间的相关视图。例如:
class Country(models.Model):
... some attributes ...
class City(models.Model):
country = models.ForeignKey(Country)
.... some attributes ...
如果直接在视图中我们可以一般性地引用City的对象,那将是非常好的:
self.parent
我已经在现在显示的Mixin中完成了这项工作,它超出了范围。但是,为了方便起见,如果我们可以将这个parent
对象直接引用为字段名称本身,那就太好了,即:
self.continent # basically just calls self.parent
这使得代码非常直观易读。一个非常简化的视图示例:
class CountryDetailView(ParentMixin, DetailView):
model = Country
parent_model = Continent
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['continent'] = self.continent # equivalent to self.parent
return context