当我只想将get
传递给另一个对象时,是否有一种优雅的方法来处理类的所有get
个请求?
这是一个Django项目,我有一个视频模型;视频可以来自不同的网站(例如,YouTube,Vimeo等)。该模型是通用的,将抓取相应的backend
来解析数据(根据网站的不同,repr
会有所不同。所有视频都具有相同的属性,但我有一个不同的backend
来正确解析它们。这是一个例子:
BACKEND_VIDEO_TYPE = (
(1, 'YouTube'),
(2, 'Vimeo'),
)
class Video(ItemBase):
video_id = models.CharField(max_length=25)
video_type = models.PositiveIntegerField(choices=BACKEND_VIDEO_TYPE)
video_data = models.TextField(editable=False)
class Meta:
unique_together = ("video_id", "video_type")
def __init__(self, *args, **kwargs):
super(Video, self).__init__(*args, **kwargs)
for k, v in BACKEND_VIDEO_TYPE:
if k == self.video_type:
VideoBackend = import_string( 'video.backends.' + v )
# load the backend that matches the video type and supply it with the data to parse
self.backend = VideoBackend(self.video_id, self.video_data)
@property
def link(self):
return self.backend.link
@property
def thumbnail(self):
return self.backend.thumbnail
@property
def is_public(self):
return self.backend.is_public()
@property
def duration(self):
return self.backend.duration
我觉得这不是解决这个问题的最好方法,但我太新了,不知道该找什么。在确定要实现哪个后端类之后,是否有一种简单的方法return self.backend.property
而无需添加后端中的每个属性?这个清单会变得相当长。通用__get__
或类似的?
感谢您的帮助。
答案 0 :(得分:1)
您可以覆盖__getattr__
类上的Video
,以便获取backend
的属性。
def __getattr__(self, attr):
try:
return getattr(self.backend, attr)
except:
raise AttributeError('No attribute named ' + attr)
__getattr__
只有在Video
对象上找不到该属性时才会调用(例如,如果用户要求Video.video_id
,则根本不会调用)所以&# 39;一种扩展Video
类的暴露属性的简洁方法。缺点是可能不明显哪些属性可用,或者它可能会暴露您不希望的某些属性。您可以通过让VideoBackend
类提供允许属性列表来解决这个问题。
def __getattr__(self, attr):
if attr in self.backend.get_allowed_attr():
return getattr(self.backend, attr)
else:
raise AttributeError('No attribute named ' + attr)