我正在尝试一些高级魔法,但我不能完全理解这个问题,这无疑是我在解决它时遇到困难的原因。
如果我做一些非常棘手的事情,并让孩子(DailyPic)知道它的父(Site),那么我可以让一切正常工作,但我不能仅仅从Site动态地做到这一点。
我试图动态地将神奇的reify (稍作修改)添加到DailyPic中,但让DailyPic实例调用Site实例上的方法。
虽然不太好用,但还行得通
class reify():
def __init__(self, wrapped, name=None):
self.wrapped = wrapped
if name is None:
from functools import update_wrapper
update_wrapper(self, wrapped)
else:
self.wrapped.__name__ = name
def __get__(self, inst, objtype=None):
if inst is None:
return self
val = self.wrapped(inst)
setattr(inst, self.wrapped.__name__, val)
return val
class Site:
def __init__(self):
self.counter = 0
def mk_filename(self, pic):
self.counter += 1
return f"{self.__class__.__name__}-{self.counter}.{pic.ext()}"
def save(self):
pic = DailyPic()
from functools import partial
pic._mk_filename = partial(self.mk_filename, pic)
return pic
class DailyPic:
def ext(self):
return 'gif' # simplified for example
@reify
def filename(self):
return self._mk_filename() # YUCK!!!
# works but ugly...
class Site1(Site): pass
class Site2(Site): pass
pic1 = Site1().save()
pic2 = Site2().save()
print(pic1.filename) # Site1-1
print(pic2.filename) # Site2-1我想要达到这样的效果:
class Site:
def save(self):
pic = DailyPic()
DailyPic.filename = reify(
functools.partial(lambda pic: self.mk_filename(pic)),
'filename'
)
return pic
# sorta works...
print(pic1.filename) # Site2-1 , should be Site1-1
print(pic2.filename) # Site2-2 , should be Site2-1如果一个高级巫师能插话,那就太棒了!
发布于 2018-12-23 12:59:13
除非你真的真的需要它是一个属性,否则就忽略reify和属性,并在每个实例上设置一个函数,该函数在运行一次时会覆盖自身。
class Site:
def save(self):
pic = DailyPic()
def filename(pic_self):
val = self.mk_filename(pic_self)
pic_self.filename = lambda _: val
return val
pic.filename = filename
return pic然后就是:
print(pic1.filename())如果你真的想让它成为一个属性,你总是可以设置pic._filename = filename,并在DailyPic上有一个返回self._filename()的属性。这基本上就是你一开始所做的。
https://stackoverflow.com/questions/53898670
复制相似问题