在之前代的demo中看到app.run(),然后启动一个应用程序,通过localhost:5000就能访问我们的视图函数。我们每次更改代码就需要手动重启,还有就是外网不能访问,或者同局域网其他机器不能访问,这些原因都藏在app.run()方法参数中。

app.run源码

def run(self, host=None, port=None, debug=None, load_dotenv=True, **options):
    """Runs the application on a local development server.

    Do not use ``run()`` in a production setting. It is not intended to
    meet security and performance requirements for a production server.
    Instead, see :ref:`deployment` for WSGI server recommendations.

    If the :attr:`debug` flag is set the server will automatically reload
    for code changes and show a debugger in case an exception happened.

    If you want to run the application in debug mode, but disable the
    code execution on the interactive debugger, you can pass
    ``use_evalex=False`` as parameter.  This will keep the debugger's
    traceback screen active, but disable code execution.

    It is not recommended to use this function for development with
    automatic reloading as this is badly supported.  Instead you should
    be using the :command:`flask` command line script's ``run`` support.

    .. admonition:: Keep in Mind

        Flask will suppress any server error with a generic error page
        unless it is in debug mode.  As such to enable just the
        interactive debugger without the code reloading, you have to
        invoke :meth:`run` with ``debug=True`` and ``use_reloader=False``.
        Setting ``use_debugger`` to ``True`` without being in debug mode
        won't catch any exceptions because there won't be any to
        catch.

    :param host: the hostname to listen on. Set this to ``'0.0.0.0'`` to
        have the server available externally as well. Defaults to
        ``'127.0.0.1'`` or the host in the ``SERVER_NAME`` config variable
        if present.
    :param port: the port of the webserver. Defaults to ``5000`` or the
        port defined in the ``SERVER_NAME`` config variable if present.
    :param debug: if given, enable or disable debug mode. See
        :attr:`debug`.
    :param load_dotenv: Load the nearest :file:`.env` and :file:`.flaskenv`
        files to set environment variables. Will also change the working
        directory to the directory containing the first file found.
    :param options: the options to be forwarded to the underlying Werkzeug
        server. See :func:`werkzeug.serving.run_simple` for more
        information.

    .. versionchanged:: 1.0
        If installed, python-dotenv will be used to load environment
        variables from :file:`.env` and :file:`.flaskenv` files.

        If set, the :envvar:`FLASK_ENV` and :envvar:`FLASK_DEBUG`
        environment variables will override :attr:`env` and
        :attr:`debug`.

        Threaded mode is enabled by default.

    .. versionchanged:: 0.10
        The default port is now picked from the ``SERVER_NAME``
        variable.
    """
    # Change this into a no-op if the server is invoked from the
    # command line. Have a look at cli.py for more information.
    if os.environ.get("FLASK_RUN_FROM_CLI") == "true":
        from .debughelpers import explain_ignored_app_run

        explain_ignored_app_run()
        return

    if get_load_dotenv(load_dotenv):
        cli.load_dotenv()

        # if set, let env vars override previous values
        if "FLASK_ENV" in os.environ:
            self.env = get_env()
            self.debug = get_debug_flag()
        elif "FLASK_DEBUG" in os.environ:
            self.debug = get_debug_flag()

    # debug passed to method overrides all other sources
    if debug is not None:
        self.debug = bool(debug)

    _host = "127.0.0.1"
    _port = 5000
    server_name = self.config.get("SERVER_NAME")
    sn_host, sn_port = None, None

    if server_name:
        sn_host, _, sn_port = server_name.partition(":")

    host = host or sn_host or _host
    # pick the first value that's not None (0 is allowed)
    port = int(next((p for p in (port, sn_port) if p is not None), _port))

    options.setdefault("use_reloader", self.debug)
    options.setdefault("use_debugger", self.debug)
    options.setdefault("threaded", True)

    cli.show_server_banner(self.env, self.debug, self.name, False)

    from werkzeug.serving import run_simple

    try:
        run_simple(host, port, self, **options)
    finally:
        # reset the first request information if the development server
        # reset normally.  This makes it possible to restart the server
        # without reloader and that stuff from an interactive shell.
        self._got_first_request = False

在app.run方法中传递这么几个参数:host=None, port=None, debug=None, load_dotenv=True

1.run参数

host参数

host参数:要监听的主机名。

if __name__ == '__main__':
    app.run(host='192.168.0.9')

上面示例代码将host设置192.168.0.9,所以启动服务后就只能通过192.168.0.9:500来访问视图视图函数。一般host设置0.0.0.0,设置成’0.0.0.0’如果在本机启动服务,通过局域网访问本机ip + port就可以访问视图函数,如果部署到服务器上,任何机器都可以通过服务器域名 + port来访问视图函数。建议设置0.0.0.0

port端口号

port:要监听主机的端口号,默认是5000,

注意:设置一般端口号时不要一些常用服务的端口号一样。如网页的端口号是8080,mysql的端口号是3036,pgsql的端口5432

if __name == '__main__':
    app.run(host='0.0.0.0', port='5000')

debug参数

debug: 如果是True开启调试模式,如果Flase关闭调试模式。一般在本地开发时,需要打开调试模式。

打开调试模式的好处就是:

load_dotenv参数

load_dotenv: 加载最近的.env.flaskenv文件来设置环境变量,一般不需要设置。

2.配置文件

开发项目中,都会创建一个配置文件,配置文件有什么好处?需要小伙伴们自行百度下。

文件结构

fisher
|-config.py
|-fisher.py

config.py

DEBUG = True

Flask读取配置

#要注意这里config文件路径,是相对入口文件的位置路径
app.config.from_object('config')

print(app.config['DEBUG'])

fisher.py

from flask import Flask

app = Flask(__name__)

#读取config中配置
app.config.from_object('config')

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

#设置debug配置
app.run(host='0.0.0.0', port='5000', debug= app.config['DEBUG'])

3.from_boject

使用app.config.from_object来装置配置,配置文件中的配置必须是大写,否则会被忽略

config.py

DEBUG = True

+ Host = '127.0.0.1'

fisher.py

from flask import Flask

app = Flask(__name__)

#读取config中配置
app.config.from_object('config')

+ print(app.config['Host'])

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

#设置debug配置
app.run(host='0.0.0.0', port='5000', debug= app.config['DEBUG'])

运行fisher.py文件,发现会抛出一个错误,KeyError: 'Host'意思是app.config['Host']没有Host变量,可是我们明明在config.py中定义Host=127.0.0.1变量,原因就是使用app.config.from_object来加载配置时,配置文件变量必须是大写

将config.py中的Host修改为大写HOST,然后修改fisher.py

print(app.config['HOST'])

然后重启fisher.py文件,发现在控制台输出:

127.0.0.1

4.app中config默认参数

我们使用app.config来加载配置文件,那么app.config默认参数是什么,下面是源码

#: Default configuration parameters.
default_config = ImmutableDict(
    {
        "ENV": None,
        "DEBUG": None,
        "TESTING": False,
        "PROPAGATE_EXCEPTIONS": None,
        "PRESERVE_CONTEXT_ON_EXCEPTION": None,
        "SECRET_KEY": None,
        "PERMANENT_SESSION_LIFETIME": timedelta(days=31),
        "USE_X_SENDFILE": False,
        "SERVER_NAME": None,
        "APPLICATION_ROOT": "/",
        "SESSION_COOKIE_NAME": "session",
        "SESSION_COOKIE_DOMAIN": None,
        "SESSION_COOKIE_PATH": None,
        "SESSION_COOKIE_HTTPONLY": True,
        "SESSION_COOKIE_SECURE": False,
        "SESSION_COOKIE_SAMESITE": None,
        "SESSION_REFRESH_EACH_REQUEST": True,
        "MAX_CONTENT_LENGTH": None,
        "SEND_FILE_MAX_AGE_DEFAULT": timedelta(hours=12),
        "TRAP_BAD_REQUEST_ERRORS": None,
        "TRAP_HTTP_EXCEPTIONS": False,
        "EXPLAIN_TEMPLATE_LOADING": False,
        "PREFERRED_URL_SCHEME": "http",
        "JSON_AS_ASCII": True,
        "JSON_SORT_KEYS": True,
        "JSONIFY_PRETTYPRINT_REGULAR": False,
        "JSONIFY_MIMETYPE": "application/json",
        "TEMPLATES_AUTO_RELOAD": None,
        "MAX_COOKIE_SIZE": 4093,
    }
)

在源码中我们可以找到config[‘DEBUG’]默认参数None

5.入口文件if__name__作用

大家看到过别人python代码中,入口文件代码经常会有下面一段代码

if __name__ == '__main__':
    app.run(host='0.0.0.0', port='5000', debug=app.config['DEBUG'])

我们来讨论下为什么添加这么一段代码,在python中如果别人导入你这个模块,如果不加判断,那么也会执行这段代码,这是我们不希望的。还有一个原因,在生产环境下,我们部署代码到服务器上,通常是使用nginx + uwsgi方式,uwsgi会加载入口文件来启动一个服务,而不在使用flask自带的app.run启动服务。如果没有这个判断,那么在服务器上就会启动两个服务,这个是不允许的。

Flask

Flask 准备工作(1) Flask URL(2) Flask 路由(3) Flask app.run参数(4) Flask 视图函数返回(5)