如何处理类层次结构中的python装饰器?
Posted
技术标签:
【中文标题】如何处理类层次结构中的python装饰器?【英文标题】:how to deal with python decorators in a class hierarchy? 【发布时间】:2020-03-29 12:09:55 【问题描述】:我正在使用DRF 开发一个 Django 项目。我还使用drf-yasg 来记录文档。
长话短说:我正在使用基于类的视图,并且我有一些非常相似的 API,我决定创建一个超类并在其中实现 API 的公共部分!为了更清楚:
class MySuperApiView(APIView):
permission_classes = [<some permission classes>]
def uncommon(self):
pass # to be override in subclasses
@swagger_auto_schema(request_body=request_body, responses=api_responses)
def post(self, *args, **kwargs):
# do some common stuff here
self.uncommon()
# do some other common stuff here
我只是在子类中覆盖 uncommon
方法:
class SomeCustomApi(MySuperApiView):
def uncommon(self):
# do specific things here
它工作正常,但我有一个小问题:每个 Api 都有自己的 api_responses
,它在超类的 swagger_auto_schema
装饰器中初始化!而且无法更改!
对于这种情况,您有什么建议?我真的很想做OOP并遵守DRY原则。
【问题讨论】:
看起来api_responses
正在作为参数传递给swagger_auto_schema
。该值在哪里定义?子类之间会有什么不同?
@PatrickHaugh 这是一个dict
,每个 API 都必须不同。我将它们声明在视图之外,而您可以看到的api_responses
是None
,它已被声明为视图之外。但是,如果可以提供帮助,它可以在里面。我试图在内部声明它并在子类中更改它的值,但它不起作用(因为它不应该)
@HamidrezaAhmadi 我认为您的问题可能会在这里得到回答:***.com/questions/42311888/… 他们使用现在已贬值的 django-rest-swagger,但它可能有助于反思。您是否尝试过指定 HTTP 方法? @swagger_auto_schema(method='GET', responses=200: UserSerializer(many=True))
@ThisIsMyName 不!这完全无关紧要。我确实知道如何处理招摇和我正在使用的框架。主要问题在标题中。我正在寻找在 OOP 中处理装饰器的最佳实践。
【参考方案1】:
我终于找到了在 Django 中做这种事情的最佳方法! (所以是的,我不知道如何在其他框架或语言中处理这样的问题!)
我使用名为method_decorator
的类装饰器将swagger_auto_schema
装饰器移动到子类。所以首先我必须导入这个方法:
from django.utils.decorators import method_decorator
然后我像这样改变了超类和子类:
class MySuperApiView(APIView):
permission_classes = [<some permission classes>]
def uncommon(self):
pass # to be override in subclasses
# <I removed decorator from here!>
def post(self, *args, **kwargs):
# do some common stuff here
self.uncommon()
# do some other common stuff here
api_responses = # responses which belong to "SomeCustomApi"
@method_decorator(name='post',
decorator=swagger_auto_schema(request_body=request_body,
responses=api_responses))
class SomeCustomApi(MySuperApiView):
def uncommon(self):
# do specific things here
它工作得很好 :) 但是我更喜欢这样的解决方案,我不必重复装饰器,而是只需初始化 responses
参数。如果您在其他语言中遇到此类问题并且您有其他语言的答案,请发布您的答案。
【讨论】:
以上是关于如何处理类层次结构中的python装饰器?的主要内容,如果未能解决你的问题,请参考以下文章
在 Swift 中实现数据存储的最佳方法是啥,如何处理类更改
如何使用 ServerManager 从类库中读取 IIS 站点,而不是 IIS express,或者提升的进程如何处理类库?