装饰器可以修改包装函数的函数签名中的类型提示吗?

时间:2020-10-07 07:16:22

标签: python python-3.x

我有一堆看起来像这样的函数:

def insert_user(user: User, db: Connection) -> None:
    ...

def add_role_to_user(user: User, role: str, db: Connection) -> None:
    ...

def create_post(post: Post, owner: User, db: Connection) -> None:
    ...

# etc.

这些功能的共同点在于它们采用了一个称为Connection的{​​{1}}参数,用于修改数据库。出于性能原因,我希望这些函数能够在彼此之间传递db参数,而不是每次都不要创建新的连接。但是,出于方便起见,我也不想每次我自己调用函数时都创建并传递db参数。

因此,我创建了一个装饰器:

db

此装饰器检查关键字参数是否包含键“ db”,如果不包含,则创建连接并将其传递给函数。用法:

def provide_db(fn):
    ...

这很完美!现在,我可以调用数据库函数而不必担心连接到数据库,并且这些函数可以相互传递db参数。

但是,要使其正确键入,装饰器需要修改已包装函数的函数签名,将@provide_db def insert_user(user: User, db: Connection) -> None: ... 参数从db更改为Connection

Python的类型提示当前是否可行?如果是这样,怎么做?


这是Optional[Connection]函数:

provide_db

2 个答案:

答案 0 :(得分:3)

功能注释在the datamodelPEP 526中记录为可写。

遵循以下简化示例:

from __future__ import annotations
from typing import Optional

def provide_db(func):
    func.__annotations__["db"] = Optional[func.__annotations__["db"]]
    return func

@provide_db
def f(db: Connection):
    pass

print(f.__annotations__)

答案 1 :(得分:2)

为此要求,将所有这些功能都放在一个类中似乎是件好事。

db_ops = DbOps(db)
db_ops.insert_user(...)
etc

然后:

                             stock

0                            AAPLApple
1                       AMZNAmazon.com
2                           FBFacebook
3                          NFLXNetflix
4                            INTCIntel
5                            TSLATesla
6                  MUMicron Technology
7                        MSFTMicrosoft
8                           NVDANVIDIA
9                    CSCOCisco Systems
11             LULULululemon Athletica
12                            EBAYeBay
13                        AVGOBroadcom
14                        QCOMQUALCOMM
15                 GILDGilead Sciences
16                  WDCWestern Digital
17                       GOOGLAlphabet
18                          BIIBBiogen
19                        GOOGAlphabet
20                URBNUrban Outfitters
21                          NTAPNetApp
22                          AABAAltaba
23                       SBUXStarbucks
24                         CELGCelgene
25                          SPLKSplunk
26                COSTCostco Wholesale
27           AMDAdvanced Micro Devices
28                          PYPLPaypal
29       REGNRegeneron Pharmaceuticals
30               AMATApplied Materials
                    ...               
Name: stock, Length: 243, dtype: object