gpt4 book ai didi

Python 访问对象属性 a la with-slots lisp

转载 作者:太空宇宙 更新时间:2023-11-03 15:39:00 24 4
gpt4 key购买 nike

common-lisp可以写

(defclass thing ()
((x :initarg :x :accessor thing-x)
(y :initarg :y :accessor thing-y)))

;; create foo of class thing with values (x=0,y=1)
(setq foo (make-instance 'thing :x 0 :y 1))

;; access attributes x and y in the scope defined by with-slots as
;; local variables and increment them
(with-slots (x y) foo
(incf x) (incf y))
;; now foo has values (x=1,y=2)

现在,在 Python3 中,我已经实现了一个数学模型,在该模型中我创建了一个变量和其他组件的字典。如果那时我需要用这些变量写一些数学表达式,在创建模型之后,我必须写类似的东西

model.expr1 = model.var1 + data.coef2 * model.var2 ....

当然,var1...varn 有更长的更具描述性的名称。

为了提高可读性我想要一些东西

with ModelSlots(model) as (var1, var2, ... varn):
model.expr1 = var1 + data.coef2 * var2 ...
...

据我了解,每个上下文管理器只返回一个对象,因此上面的解决方案应该是不可能的。

你知道如何在 python 中实现它吗?

当然,最明显的解决办法是

var1 = model.var1
var2 = model.var2
...

但这很冗长,难以阅读,使上下文更加困惑,并且还可能导致模糊的错误,因为我可能会无意中将一些局部 var 变量初始化为错误的值。

每个变量都有多个上下文管理器

with Var1(model) as var1:
with Var2(model) as var2:
...

也不是解决方案,因为我可以在同一范围内使用多个变量,我可能想快速更改或添加新变量。必须为它们中的每一个定义一个上下文管理器会太麻烦。

TIA

编辑1

评论 Felix 解决方案。插槽的排序/匹配可以通过以下方式解决:

from bunch import Bunch

class ModelSlots:

def __init__(self, model, *slots):
self._model = model
self._slots = list(map(lambda x: getattr(model,x), slots))

def __enter__(self):
return self._slots

def __exit__(self, *args):
pass


if __name__ == '__main__':
model = Bunch()
model.foo = 1
model.bar = 2
with ModelSlots(model, "bar", "foo") as (bar,foo):
print((foo, bar))
# prints (1,2)

但是你需要重复插槽的名称两次,带引号和不带引号......

最佳答案

Python 支持元组解包,即使在 with 语句中也是如此。请参阅下面的实际操作:

class ModelSlots:

def __init__(self, model):
self._model = model

def __enter__(self):
return self._model.values()

def __exit__(self, *args):
pass


if __name__ == '__main__':
model = {"foo": 1, "bar": 2}
with ModelSlots(model) as (foo, bar):
print(foo + bar)
# prints 3

这是你要的吗?

我不确定这在总体上是否是个好主意。 with 语句中的名称 foobar 与模型中的变量名称无关,因此很容易意外混淆它们(例如通过更改它们的顺序) .这可能会导致非常微妙的错误。

总而言之,我认为它“有点”可能,但根据您的应用程序可能会很危险。

关于Python 访问对象属性 a la with-slots lisp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53776132/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com