V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
just1
V2EX  ›  Python

Python 怎么声明变量比较优雅

  •  
  •   just1 · 2020-09-03 18:21:27 +08:00 · 2500 次点击
    这是一个创建于 1575 天前的主题,其中的信息可能已经有所发展或是发生改变。

    问题是这样:我需要一个全局变量,但是在之后的 async function 里面才会对其进行赋值,这是我几个尝试,但是 pycharm 多少都会报 Warning

    先声明为 None

    app = FastAPI()
    conn_pool = None
    
    @app.on_event("startup")
    async def startup():
        global conn_pool
        conn_pool = await asyncpg.create_pool()
    
    @app.get('/')
    async def index():
        async with conn_pool.acquire() as conn:
            pass # do something
    

    这样底下的所有 conn_pool 的操作都会报Cannot find reference 'xxx' in 'None'

    先声明为 None,用 type hint 标记

    app = FastAPI()
    conn_pool: asyncpg.pool.Pool = None
    
    @app.on_event("startup")
    async def startup():
        global conn_pool
        conn_pool = await asyncpg.create_pool()
    
    @app.get('/')
    async def index():
        async with conn_pool.acquire() as conn:
            pass # do something
    

    这样在conn_pool: asyncpg.pool.Pool = None这一行会报Expected type 'Pool', got 'None' instead

    不声明

    app = FastAPI()
    
    @app.on_event("startup")
    async def startup():
        global conn_pool
        conn_pool = await asyncpg.create_pool()
    
    @app.get('/')
    async def index():
        async with conn_pool.acquire() as conn:
            pass # do something
    

    可以用,但是在global conn_pool会报Global variable 'conn_pool' is undefined at the module level


    虽然所有代码都可以运行,但是都会错误提示,感觉很不舒服。求助有没有完美的解决方案。

    我这里需要全局变量的原因是 conn_pool 需要在其他函数内使用

    9 条回复    2020-09-03 18:48:14 +08:00
    BBCCBB
        1
    BBCCBB  
       2020-09-03 18:25:58 +08:00
    试试 typing.Union[asyncpg.pool.Pool, None] ?
    just1
        2
    just1  
    OP
       2020-09-03 18:27:17 +08:00
    @BBCCBB #1 一样会有 Cannot find reference 'xxx' in 'None',应该是因为我直接赋值为 None 的原因
    013231
        3
    013231  
       2020-09-03 18:27:18 +08:00
    type hint,
    013231
        4
    013231  
       2020-09-03 18:27:25 +08:00
    conn_pool: asyncpg.pool.Pool = None
    改为
    013231
        5
    013231  
       2020-09-03 18:27:46 +08:00
    conn_pool: asyncpg.pool.Pool
    去掉" = None"即可
    just1
        6
    just1  
    OP
       2020-09-03 18:30:30 +08:00
    @013231 #5 喔,这个应该是最优解了,之前我搜索 define variable without value 没找到这个方式,谢谢
    HFcbyqP0iVO5KM05
        7
    HFcbyqP0iVO5KM05  
       2020-09-03 18:30:34 +08:00 via Android
    conn_pool: asyncpg.pool.Pool = None # noqa
    laike9m
        8
    laike9m  
       2020-09-03 18:37:59 +08:00   ❤️ 1
    首先,PyCharm 的警告都是可以关的,而且控制粒度比较细,你要是不爽关了对应的警告就行了

    其次,这种情况一般用 typing.Optional 就可以解决:
    https://docs.python.org/3/library/typing.html#typing.Optional
    just1
        9
    just1  
    OP
       2020-09-03 18:48:14 +08:00
    @gulu #7
    @laike9m #8
    按照#5 的方案就可以解决了 conn_pool: asyncpg.pool.Pool,不需要附值

    @laike9m #8 关了是最后的退路~
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3402 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 04:55 · PVG 12:55 · LAX 20:55 · JFK 23:55
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.