如何解决使用实例名称访问实例变量
我有一堂这样的课:
Class PropertyExpr:
def __init__(self,value,expr):
self.value = value
self.expr = expr
假设我像这样初始化类:
prop1 = PropertyExpr(5,"test")
我明白,如果我想访问 value
或 expr
,我会调用 prop1.value
或 prop1.expr
。
但是,我想让它在我调用 prop1
时自动返回 prop1.value
。 prop1.expr
仍然可以访问 expr
变量
由于 value
可以是任何数据类型,我认为使用 __str__
行不通。
感谢您的帮助!
编辑:这是我目前的方法,但它只适用于 int,我需要扩展它以便它也适用于其他数据类型,例如列表:
class PropertyExpr(int):
def __new__(self,value: int,expr: Optional[str]=None,*args,**kwargs):
return int.__new__(self,**kwargs)
def __init__(self,**kwargs):
int.__init__(value,**kwargs)
if expr is None:
self.expr = str(value)
else:
self.expr = expr
所以当我创建一个实例时:
prop1 = PropertyExpr(5,"test")
所以当我使用 prop1
时,它会返回 5 和 prop1.expr = "test"
。
解决方法
如果您所说的“调用”实际上是指调用而不仅仅是“访问”,那么您可以简单地实现一个 __call__
方法:
class PropertyExpr:
def __init__(self,value,expr):
self.value = value
self.expr = expr
def __call__(self):
return self.value
prop1 = PropertyExpr(5,"test")
val = prop1()
print(val)
输出:
5
在这种情况下,调用 prop1()
的结果实际上可以是任何东西。
除此之外,你想要的是不可能的。您可以覆盖 __new__
方法,但这也会改变您创建的内容的类型。因此,如果您返回 5
,您的对象将是 5
,但它也将是一个 int
,不再是 PropertyExpr
的实例,您的所有附加属性都将是丢失:
class PropertyExpr():
def __new__(cls,expr):
return value
def __init__(self,expr):
self.value = value
self.expr = expr
prop1 = PropertyExpr(5,"test")
print(prop1,type(prop1))
try:
print(prop1.expr)
except Exception as e:
print(e)
输出:
5 <class 'int'>
'int' object has no attribute 'expr'
经过一些尝试,我找到了一种动态更改构造函数类型的方法,但是我建议不要实际使用它:
class PropertyExpr:
def __new__(cls,tp,*args,**kwargs):
return type("FakeType",(tp,),kwargs)(value)
prop1 = PropertyExpr(int,5,expr="expr int")
print(prop1," -> ",prop1.expr)
prop2 = PropertyExpr(list,"5",expr="expr list")
print(prop2,prop2.expr)
prop3 = PropertyExpr(str,"abc",expr="expr string")
print(prop3,prop3.expr)
输出:
5 -> expr int
['5'] -> expr list
abc -> expr string
您可以将您希望子类化的类型作为第一个参数传递,第二个参数应该是该类型的构造函数接受的值,然后您可以传入任意 kwargs,这些 kwargs 将作为属性添加到创建的对象中。
有没有办法使 type(prop1) 仍然是 PropertyExpr?编辑:例如,如果我们可以做 isinstance(prop1,PropertyExpr) = True 那么一切都会很完美
我无法让它工作(这并不意味着其他人不能),但我设法使其与多继承一起工作,因此您可以使用isinstance(prop1,PropertyExprMixin)
:
class PropertyExprMixin:
pass
class PropertyExpr:
def __new__(cls,**kwargs):
return type("PropertyExprMixin",PropertyExprMixin),prop1.expr,type(prop1),isinstance(prop1,int),PropertyExprMixin))
prop2 = PropertyExpr(list,prop2.expr,type(prop2),isinstance(prop2,list),PropertyExprMixin))
prop3 = PropertyExpr(str,prop3.expr,type(prop3),isinstance(prop3,str),PropertyExprMixin))
输出:
5 -> expr int <class '__main__.PropertyExprMixin'> True True
['5'] -> expr list <class '__main__.PropertyExprMixin'> True True
abc -> expr string <class '__main__.PropertyExprMixin'> True True
,
你可以这样做:
OwnerID Pet(s)
1 X,Y,and Z
2 Apples
输出:
class PropertyExpr(int):
def __new__(cls,expr):
obj = super().__new__(cls,value)
obj.expr = expr
return obj
var = PropertyExpr(5,"test")
print(var)
print(var.expr)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。