可选的/required/keyword-only装饰器参数很容易实现。

decorator-args的Python项目详细描述


buildcode qualitycode healthcoveragepypigithublicense: MIT

这个迷你图书馆远不是革命性的,也不是必不可少的,但它的功能可能对某些人有用。 这是一个混乱的想法和特点,我并不真的觉得是坚如磐石,但我认为这不是一个 把它放归野外是不可饶恕的罪恶感。在最坏的情况下,您可以打开“请销毁此代码/库” 在其github页面上发布。

Installation

pip install decorator-args

或者,您也可以从以下位置下载发行版:

Usage

Problem to solve

下面的代码片段显示了两个示例:

  1. 在不带任何参数的情况下应用名为argless的装饰器。
  2. 应用名为argful的装饰器,该装饰器在应用前接收参数。
#1@arglessdefdecorated_function():...#2@argful('arg1_value',arg2='arg2_value')defdecorated_function():...

这个库试图使实现接收参数的decorator(如上面的argful_decorator)变得更容易。 除此之外,它还提供了一些相关的额外功能(可选的和仅限关键字的decorator参数)。

How this library helps

以前使用的argfuldecorator可以用无数种方法实现,但是有两种最标准的方法可以实现它 如果没有这个库,则如下所示:

  1. “初始风格”功能实现:
defargful(arg1,arg2='arg2_default'):# TODO: Validate and pre-process decorator args as early as possible for easier debuggingdefdecorate(decoratable):@functools.wraps(decoratable)defwrapper(*args,**kwargs):# TODO: Manipulate the input and output of the wrapped# decoratable object and use arg1 and arg2 if you want...returndecoratable(*args,**kwargs)returnwrapperreturndecorate
  1. 类实现:
classargful(object):def__init__(self,arg1,arg2='arg2_default'):# TODO: Validate and pre-process decorator args as early as possible for easier debuggingself.arg1=arg1self.arg2=arg2def__call__(self,decoratable):@functools.wraps(decoratable)defwrapper(*args,**kwargs)# TODO: Manipulate the input and output of the wrapped# decoratable object and use self.arg1 and self.arg2 if you want...returndecoratable(*args,**kwargs)returnwrapper

此库提供的decorator_args.decorator_argsdecorator可以从 示例1中的“inception style”实现使代码更简单、可读性更强:

fromdecorator_argsimportdecorator_args@decorator_argsdefargful(decoratable,arg1,arg2='arg2_default'):@functools.wraps(decoratable)defwrapper(*args,**kwargs):# TODO: Manipulate the input and output of the wrapped# decoratable object and use arg1 and arg2 if you want...returndecoratable(*args,**kwargs)returnwrapper

同时,此库还提供以下附加功能:

  • 它可以强制为您的decorator传递仅关键字的参数。在某些情况下,这是可取的,因为它可以 代码更易于阅读和理解:
# Decorator implementation with keyword-only decorator arguments:@decorator_args(keyword_only=True)defargful(decoratable,arg1,arg2='arg2_default'):...# This would fail with a ``TypeError('This decorator receives only keyword arguments')``@argful('arg1_value',arg2='arg2_value')defdecorated_function():...# This is OK because all args are passed as keyword args@argful(arg1='arg1_value',arg2='arg2_value')defdecorated_function():...
  • 如果您的decorator没有必需的参数,并且您使用此库的optional功能,则 如果不想向装饰符传递任何参数,请在不带参数列表的情况下应用装饰符:
# Decorator implementation with optional argument list:# Note that our decorator doesn't have required args other than the decoratable object:@decorator_args(optional=True)defargful(decoratable,arg1='arg1_default',arg2='arg2_default'):...# This works because of using `optional=True` above:@argfuldefdecorated_function():...# This would work even without `optional=True` in our decorator implementation:@argful()defdecorated_function():...# Of course passing actual args also works as expected:@argful('arg1_value','arg2_value')defdecorated_function():...

Library interface

库提供了一个decorator_args.decorator_argsdecorator,它是库的主要“主力”,并且 一组其他装饰器,它们只是前面提到的主装饰器周围的方便助手。 从语法上看,这些修饰符的参数是可选的,仅限关键字。

Main “entrypoint”

decorator_args.decorator_args(*,keyword_only=false,optional=false,is_decoratible_object=none)

The main decorator of the library. All other decorators are just convenience helpers based on this one.

  • ^{tt8}$: Makes the arguments of your decorator keyword-only. Passing any positional arguments to your decorator will result in a ^{tt9}$ with an appropriate error message.

  • ^{tt6}$: ^{tt11}$ allows you to write ^{tt12}$ instead of ^{tt13}$. When you apply your decorator without passing any args to it you can omit the empty brackets that specify the empty decorator argument list.

  • ^{tt14}$: This argument can be used only when ^{tt15}$ and ^{tt11}$. When the argument list of your decorator is optional and you apply your decorator by passing only a single positional argument to the decorator this library has hard time to decide whether that single positional argument is an optional decorator argument or a decoratable object. This decision is made by the library function ^{tt17}$ function which returns ^{tt18}$ if the given single positional argument is a function, method, or class. This default behavior is good in most of the cases when your decorator receives only simple arguments like integers, strings, bools, etc… However if your decorator can receive a single positional argument that can be a function, method, or class, then the default behavior isn’t suitable. There are several workarounds to this problem, one of them is providing your own ^{tt19}$ implementation through the currently documented decorator argument. You probably have additional info to make an accurate distinction between decorator arguments and decoratable objects to provide a working ^{tt19}$ implementation.

    In such pathological edge-cases you can also use the following workarounds besides the previously documented custom ^{tt19}$ implementation:

    • When you apply your decorator with only a single argument that is a function/method/class you can pass the argument as a keyword-argument. This way it will be detected as a decorator argument for sure. This is however just a dirty hack that still leaves chance for the users of your decorator to make an error. This can result in long debugging sessions.
    • You can make your optional arguments keyword-only with ^{tt22}$. This completely eliminates the problem.
    • Don’t make the argument list of this decorator optional. With a required decorator argument list this problem isn’t present.

Helpers: convenience API

便利api提供了一组decorator,它们只是围绕main的“包装器” decorator_args.decorator_args装饰器。这些方便的装饰器只是绑定了一些主装饰器 一些常量的参数。

decorator_args.可选的_decorator_args(*,keyword_only=false,is_decorated_object=none)

Works just like the main ^{tt5}$ decorator with ^{tt11}$.

decorator_args.keyword_only_decorator_args(*,optional=false)

Works just like the main ^{tt5}$ decorator with ^{tt22}$.

decorator_args.可选_keyword_only_decorator_args

Works just like the main ^{tt5}$ decorator with ^{tt11}$ and ^{tt22}$.

Implementing your decorators in a “twisted” way

库的复杂实现确保了此库提供的装饰器可以应用于 甚至在一些异国情调的情况下,装饰师:

When your decorator is a bound instance/class/static method

classAnyClass(object):@decorator_argsdefdecorator_when_bound(self,decoratable,arg1,arg2):...# It is important to apply @decorator_args after @classmethod!@decorator_args@classmethoddefdecorator_when_bound_2(cls,decoratable,arg1,arg2):...# It is important to apply @decorator_args after @statimethod!@decorator_args@staticmethoddefdecorator_when_bound_3(decoratable,arg1,arg2):...any_class_instance=AnyClass()decorator_with_args=any_class_instance.decorator_when_bounddecorator_with_args_2=AnyClass.decorator_when_bound_2decorator_with_args_3a=any_class_instance.decorator_when_bound_3decorator_with_args_3b=AnyClass.decorator_when_bound_3

When your decorator is a bound __call__ magic (instance)method

classAnyClass(object):@decorator_argsdef__call__(self,decoratable,arg1,arg2):...# Because of the syntactic sugar provided by python it is as simple as:decorator_with_args=AnyClass()

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java以编程方式从TableLayout中删除所有行   Java Web Sart Ubuntu12.1。加载资源(图像)   人们如何让Java SPNEGO客户端在Windows中工作?   java Eclipselink:ObjectArrayMapping和ClassDescriptor   控制台中带有引号/空格的java Javafx命名参数   java创建服务失败:找不到对象?   java Hazelcast:如何在测试期间禁用自动发现?   使用TuckyUrlRewriteFilter rermoteaddr的java块IP   javascript如何在angular 4中进行同步http调用   输入字符串的java排列   java Jenkins不是以Xrs Xmx2048m XX:MaxPermSize=512m(windows)开始的   AWS EMR上的java avro错误   java从两个ArrayList中提取特定连接的对象,组合这些相关对象并从子类中打印   java从主题中删除什么时间点消息?   谷歌像素设备上的java InvalidKeyException   java如何在执行测试后重建项目   java Android 2.2 readUTF()socket问题   按下安卓设备上的“后退”按钮后java Toast没有完成?