Python 中装饰器的延后使用解决循环导入的问题

装饰器作为 Python 中一个很重要的组成部分,除了装饰器的常规用法之外,本文只是介绍一下装饰器的延迟用法。本文中出现的代码是基于Flask框架。

在main.py文件中有如下代码:

# 本期主题是利用装饰器的延后使用解决循环导入的问题
from flask import Flask
from login import login
from register import register

# 创建Flask的实例化对象
app = Flask(__name__)
# 注册路由函数


@app.route("/")
def index():
    return 'index page'


@app.route('/register/')
def register():
    return 'register page'


@app.route('/login/')
def login():
    return 'login page'


if __name__ == '__main__':
    app.run(debug=True)

在web开发过程中,我们通常需要注册多个视图,如果将多个视图逻辑存放在一个py文件中,导致 Py文件代码冗余,不便于复用。我们将不同视图提取出来,作为一个独立的py文件:

login.py

from main import app

@app.route('/login/')
def login():
    return 'login page'

register.py

from main import app

@app.route('/register/')
def register():
    return 'register page'

此时main.py为:

# 本期主题是利用装饰器的延后使用解决循环导入的问题
from flask import Flask
from login import login
from register import register

# 创建Flask的实例化对象
app = Flask(__name__)
# 注册路由函数


@app.route("/")
def index():
    return 'index page'



if __name__ == '__main__':
    app.run(debug=True)

运行主文件,将会出现如下错误提示:

ImportError: cannot import name 'login'

我们已经在mian.py文件中导入了login 和register模块,为什么还会出现上述错误呢?

主要原因在于:出现了循环导入文件。

解决这个问题有方法:

方法一(不推荐):

调整导入文件代码的位置。在程序开发中,我们常说:要将不同功能的代码放在合适的位置。什么是合适的位置呢?这个问题只能在程序开发的过程中自行体会。

现在调整main.py文件中导入模块的代码位置:

main.py

# 本期主题是利用装饰器的延后使用解决循环导入的问题
from flask import Flask


# 创建Flask的实例化对象
app = Flask(__name__)
# 注册路由函数


@app.route("/")
def index():
    from login import login
    from register import register
    return 'index page'



if __name__ == '__main__':
    app.run(debug=True)

此时启动 main.py 程序正常运行。

此时导入外部框架的代码位置为合适的位置,请自行体会。

方法二(推荐):

使用装饰器延迟加载的方法,解决循环导入的问题。

# 本期主题是利用装饰器的延后使用解决循环导入的问题
from flask import Flask
from login import login
from register import register

# 创建Flask的实例化对象
app = Flask(__name__)
# 注册路由函数


@app.route("/")
def index():
    return 'index page'


# 利用装饰器可以延后使用来解决循环导入的问题
app.route('/login/')(login)
app.route('/register/')(register)


if __name__ == '__main__':
    app.run(debug=True)

在此启动 main.py,程序正常运行。

如果你熟悉Flask框架,应该使用BluePrint 来解决上述问题,本文只是为了说明在 Python 中可以使用装饰器的延迟加载方法。

你可能感兴趣的:(python,知识点)