[PYTHON] How to define Decorator and Decomaker in one function

When defining fixtures in Pytest, the decorator fixture supports both parentheses and arguments, such as(scope = "session"), and parentheses and arguments. The following code is an example of both uses in the Pytest documentation.

Source: Pytest documentation

python


@pytest.fixture
def smtp():
    return smtplib.SMTP("smtp.gmail.com")

python


@pytest.fixture(scope="module")
def smtp():
    return smtplib.SMTP("smtp.gmail.com")

I tried to find out how to describe such a decorator.

To be precise, in the former parenthesis and no-argument usage, fixture is called a decorator, and in the latter parenthesis and no-argument usage, fixture is a decorator-creating decorator (decomaker). .. ([PEP 318 --Decorators for Functions and Methods] (https://www.python.org/dev/peps/pep-0318/#current-syntax))

In Pytest's fixture source, the fixture was implemented as follows:

python


def fixture(scope="function", params=None, autouse=False, ids=None, name=None):
    """ (return a) decorator to mark a fixture factory function.

    This decorator ....(Abbreviation)    
    """
    if callable(scope) and params is None and autouse == False:
        # direct decoration
        return FixtureFunctionMarker(
                "function", params, autouse, name=name)(scope)
    if params is not None and not isinstance(params, (list, tuple)):
        params = list(params)
    return FixtureFunctionMarker(scope, params, autouse, ids=ids, name=name)

If fixture is used as a decorator with parentheses and no arguments, the scope argument to fixture is passed the function object defined in the function definition following the decorator (smtp in the example above). I will.

ʻIf callable (on the line of ..., check if scope is callable(at the same time, if the argument that follows is the default value), and if so, decomakerFixtureFunctionMakerCreate an instance of, and passscope to its () `.

On the other hand, if fixture is used with parentheses and arguments, it returns the decorator (decomaker instance) itself. Python passes smtp to the returned decorator and assigns the return value to the name smtp.

It's unpleasant to use the initial argument scope for a completely different purpose, but it can be aggregated into a single function, creating a user-friendly decorator interface.

Recommended Posts

How to define Decorator and Decomaker in one function
How to use Decorator in Django and how to make it
How to convert 0.5 to 1056964608 in one shot
How to dynamically define variables in Python
How to use is and == in Python
How to generate permutations in Python and C ++
How to define your own target in Sage
[Python] How to use hash function and tuple.
How to write async and await in Vue.js
How to Mock a Public function in Pytest
How to plot autocorrelation and partial autocorrelation in python
[Road to Python Intermediate] Define __getattr__ function in class
How to do zero-padding in one line with OpenCV
[Python] How to sort dict in list and instance in list
How to get RGB and HSV histograms in OpenCV
How to store Python function in Value of dictionary (dict) and call function according to Key
Covector to think in function
How to call a function
How to define Go variables
How to develop in Python
How to use the decorator
How to embed multiple embeds in one message with Discord.py
How to swap elements in an array in Python, and how to reverse an array.
Foreigners talk: How to name classes and methods in English
How to check ORM behavior in one file with django
[Python] How to play with class variables with decorator and metaclass
How to use pyenv and pyenv-virtualenv in your own way
[Python] How to write an if statement in one sentence.
[Introduction to Udemy Python 3 + Application] 36. How to use In and Not
How to define multiple variables in a python for statement
How to create and use static / dynamic libraries in C
How to sample from any probability density function in Python
Comparison of how to use higher-order functions in Python 2 and 3
How to get all the keys and values in the dictionary
[Blender] How to handle mouse and keyboard events in Blender scripts
[TF] How to load / save Model and Parameter in Keras
How to execute external shell scripts and commands in python
How to create dataframes and mess with elements in pandas
[ROS] How to write Publisher and Subscriber on one node
How to log in to AtCoder with Python and submit automatically
How to do "Lending and borrowing JS methods (the one who uses apply)" in Python
How to auto-update App Store description in Google Sheets and Fastlane
How to handle session in SQLAlchemy
How to use the zip function
How to install OpenCV on Cloud9 and run it in Python
How to compare lists and retrieve common elements in a list
How to install and use Tesseract-OCR
How to use classes in Theano
How to write soberly in pandas
How to collect images in Python
Repeated @ app.callback in Dash How to write Input and State neatly
How to give and what the constraints option in scipy.optimize.minimize is
[Python 3.8 ~] How to define a recursive function smartly with a lambda expression
How to update Spyder in Anaconda
How to use SQLite in Python
How to use functions in separate files Perl and Python versions
How to smartly define objects that are commonly used in View
How to make a recursive function
Difference in how to write if statement between ruby ​​and python
How to combine all CSVs in a folder into one CSV
How to reflect CSS in Django