python - 如何在从基类生成的类上创建@property?
问题描述
我想在一个类上动态生成属性,我希望在“基”类上生成它们。为了说明这个问题,我在这里使用伪代码来说明我如何不知道方法的名称。
class Base:
def __init__(self):
for n in range(1,3):
setattr(self, f"func{n}", property(lambda self_=self: {f"func{n}": self_}))
class A(Base):
pass
然后我运行:
>>> a = A()
>>> a.func1
<property object at 0x7f67c1342598>
但是,我期望得到以下结果:
>>> a = A()
>>> a.func1
{'func1': <A object at 0x7f9ccec77198>}
在我看来,property()
通话没有按预期工作。我究竟做错了什么?
解决方案
我不确定您为什么不将其用作装饰器,这是一个我们不直接调用属性的示例:
class Base:
@property
def func(self):
return {"self": self}
class A(Base):
pass
print(A().func)
{'self': <__main__.A object at 0x0000018CC01DDC10>}
回复已编辑的问题
当然这是可能的,但我们必须将属性绑定到类,而不是实例。我们也不能self_
按照我们实际想要的每个实例的self
.
class Base:
def __init__(self):
for n in range(1, 3):
setattr(self.__class__, f"func{n}", property(lambda self_, n_=n: {f"func{n_}": self_}))
class A(Base):
pass
print(A().func1)
print(A().func2)
{'func1': <__main__.A object at 0x00000139C12B5FD0>}
{'func2': <__main__.A object at 0x00000139C12B5FD0>}
一些断言来确保参数是正确的:
a1 = A()
a2 = A()
assert a1.func1["func1"] is a1
assert a1.func2["func2"] is a1
assert a2.func1["func1"] is a2
assert a2.func2["func2"] is a2
我们在每个实例中存储唯一对象的另一个示例
我担心前面的答案,因为它只是覆盖类方法。在这个例子中,我们仍然在创建每个实例时覆盖类方法,但我们还在每个实例中为每个 func 存储一个唯一的对象,我相信这更接近您正在寻找的内容。存储在类中的简单计数器用于可视化它。
class Base:
count = 0
def __init__(self):
for n in range(1, 3):
func_name = f"func{n}"
var_name = f"_{func_name}_var"
setattr(self, var_name, {func_name: self, "count": Base.count})
setattr(self.__class__, func_name, property(lambda self_, name=var_name: getattr(self_, name)))
Base.count += 1
class A(Base):
pass
a1 = A()
a2 = A()
print(a1.func1)
print(a1.func2)
print(a2.func1)
print(a2.func2)
{'func1': <__main__.A object at 0x0000019298925FD0>, 'count': 0}
{'func2': <__main__.A object at 0x0000019298925FD0>, 'count': 1}
{'func1': <__main__.A object at 0x0000019298925F70>, 'count': 2}
{'func2': <__main__.A object at 0x0000019298925F70>, 'count': 3}
推荐阅读
- android - 如何获取模块中没有应用程序类的非活动类的上下文
- c# - 无法重新创建子游戏对象统一c#
- python - pandas 数据块索引
- angular - Angular 7 路由 concat 导致编译错误
- c++ - 为什么模板函数仅基于返回类型适用于 C++?
- r - 如何创建逻辑向量的排列?
- c# - ASP.NET Core 2.2 的迁移问题“不能标记为可为空/可选,因为它已包含在密钥中”
- sharepoint - 即使我删除了 sharepoint 中的某些内容,如何在 30 天内恢复记录?
- google-cloud-platform - 如何通过 GCP 部署管理器 API 创建项目
- python-2.7 - 如何控制字段的输入格式?