码迷,mamicode.com
首页 > 其他好文 > 详细

Flask------一些面试题

时间:2019-05-11 21:24:12      阅读:183      评论:0      收藏:0      [点我收藏+]

标签:服务器   __call__   nosql数据库   存在   middle   csrf   验证   gevent   task   

1.请手写一个flask的hello world。

hello.py中

#coding = utf-8

# 第一步:导入Flask类
from flask import Flask
app = Flask(__name__)

@app.route("/")
def helloworld():
    return "<h1>hello world</h1>"

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

2.Flask框架的优势及适用场景?

优势:

1.轻量;(Micro Framework)

2.简洁

3.扩展性好*

4 第三方库的选择面广,开发时可以结合自己喜欢用的轮子,也可以结合强大的python库

5.核心(werzeugjinja2),jinja2就是指模板引擎。

应用场景:

  适用于小型网站,适用于开发web服务的API;

  开发大型网站也毫无压力,但是代码架构需要开发者自己设计;

Flask和Nosql数据库的结合优于django

3.Flask框架组件

flask_sqlalchemy:将Flask和SQLAlchemy很好的结合在一起,如django中的ORM操作

flask_script:用于生成命令,在项目根目录路径下使用命令;例如:python manage.py runserver 

flask_migrate:用来实现数据库迁移(依赖flask_script)

flask-session:session放在redis里面

blinker:信号-触发信号

  PS:# flask中的信号blinker 信号主要是让开发者可是在flask请求过程中定制一些行为。 或者说flask在列表里面预留了几个空列表,在里面存东西。 简言之,信号允许某个‘发送者‘通知‘接收者‘有事情发生了

4.Flask蓝图的作用

# blueprint把实现不同功能的module分开.也就是把一个大的App分割成各自实现不同功能的module.

# 在一个blueprint中可以调用另一个blueprint的视图函数, 但要加相应的blueprint名.

通常情况下,我是使用flask框架的项目组织结构是这样的:

技术图片

我们看看视图方法:

#views.py
from app import app


@app.route(/user/index)
def index():
    return user_index

@app.route(/user/show)
def show():
    return user_show

@app.route(/user/add)
def add():
    return user_add

@app.route(/admin/index)
def adminindex():
    return admin_index

@app.route(/admin/show)
def adminshow():
    return admin_show

@app.route(/admin/add)
def adminadd():
    return admin_add

#从视图方法中,我们看到有6个视图,分别对应admin,user两个不同用户的3个功能index,add,show.
这样写显然没问题,但是明显与python提倡的模块化冲突;

当然根据Pythonic特点,我们肯定希望尽可能的把代码尽量的模块化,让我们的代码看起来更加的优雅和顺畅,这个时候flask.Blueprint(蓝图)就派上用场了

一个蓝图定义了可用于单个应用的视图,模板,静态文件等等的集合

上面的例子中只有两个组件(模块)admin,user,我们可以创建名为admin.py和user.py的两个文件,分别在里面创建两个蓝图的实例对象admin,user.

#admin.py
from flask import Blueprint,render_template, request

admin = Blueprint(admin,__name__)

@admin.route(/index)
def index():
    return render_template(admin/index.html)

@admin.route(/add)
def add():
    return admin_add

@admin.route(/show)
def show():
    return admin_show

#要想创建一个蓝图对象,你需要import flask.Blueprint()类并用参数name和import_name初始化。import_name通常用__name__,一个表示当前模块的特殊的Python变量,作为import_name的取值。

#user.py

from
flask import Blueprint, render_template, redirect user = Blueprint(user,__name__) @user.route(/index) def index(): return render_template(user/index.html) @user.route(/add) def add(): return user_add @user.route(/show) def show(): return user_show

视图函数已经分开了 再看看view.py

#view.py

from app import app
from .admin import admin
from .user import user
#这里分别给app注册了两个蓝图admin,user
#参数url_prefix=‘/xxx‘的意思是设置request.url中的url前缀,
#即当request.url是以/admin或者/user的情况下才会通过注册的蓝图的视图方法处理请求并返回
app.register_blueprint(admin,url_prefix=/admin)
app.register_blueprint(user, url_prefix=/user)

再看看使用蓝图后的项目结构:

技术图片

如果项目不大的话就没有必要使用蓝图了,我们甚至可以把除了所有css,js,html的代码都写到一个文件中去。

5.列举Flask使用的第三方组件

# 第三方组件:

  Wtforms:快速创建前端标签、文本校验

  dbutile:创建数据库连接池

  gevent-websocket:实现websocket

# 自定义Flask组件

  auth认证

  参考flask-login

6.简述Flask上下文管理流程。

Flask中有两种上下文,请求上下文应用上下文

request和session都属于请求上下文对象。

  request:封装了HTTP请求的内容,针对的是http请求。举例:user = request.args.get(‘user‘),获取的是get请求的参数。

  session:用来记录请求会话中的信息,针对的是用户信息。举例:session[‘name‘] = user.id,可以记录用户信息。还可以通过session.get(‘name‘)获取用户信息

current_app和g都属于应用上下文对象。

  current_app:表示当前运行程序文件的程序实例。

  g:处理请求时,用于临时存储的对象,每次请求都会重设这个变量。比如:我们可以获取一些临时请求的用户信息。

  当调用app = Flask(_name_)的时候,创建了程序应用对象app;
  request 在每次http请求发生时,WSGI server调用Flask.call();然后在Flask内部创建的request对象;
  app的生命周期大于request和g,一个app存活期间,可能发生多次http请求,所以就会有多个request和g。
  最终传入视图函数,通过return、redirect或render_template生成response对象,返回给客户端。
他们的区别:

 请求上下文:保存了客户端和服务器交互的数据。 应用上下文:在flask程序运行过程中,保存的一些配置信息,比如程序文件名、数据库的连接、用户信息等

# a、简单来说,falsk上下文管理可以分为三个阶段: 
  1、请求进来时:将请求相关的数据放入上下问管理中
  2、在视图函数中:要去上下文管理中取值 
  3、请求响应:要将上下文管理中的数据清除#
# b、详细点来说:  
  1、请求刚进来:
    将request,session封装在RequestContext类中
    app,g封装在AppContext类中
    并通过LocalStack将requestcontext和appcontext放入Local类中
  2、视图函数中:
    通过localproxy--->偏函数--->localstack--->local取值
  3、请求响应时:
    先执行save.session()再各自执行pop(),将local中的数据清除

7.Flask中g的作用

g:gloal

1.g对象是专门用来来保存用户数据的;

2.g对象在一次请求中的所有的代码的地方,都是可以使用的

# g是贯穿于一次请求的全局变量,当请求进来将g和current_app封装为一个APPContext类,
# 再通过LocalStack将Appcontext放入Local中,取值时通过偏函数在LocalStack、local中取值;
# 响应时将local中的g数据删除

8.如何编写flask的离线脚本

 

9.Flask中上下文管理主要是涉及到了哪些相关的类?并描述类主要的作用

RequestContext  #封装进来的请求(赋值给ctx)
AppContext      #封装app_ctx
LocalStack      #将local对象中的数据维护成一个栈(先进后出)
Local           #保存请求上下文对象和app上下文对象

10.为什么要Flask把Local对象中的值stack维护程一个列表

# 因为通过维护成列表,可以实现一个栈的数据结构,进栈出栈时只取一个数据,巧妙的简化了问题。
# 还有,在多app应用时,可以实现数据隔离;列表里不会加数据,而是会生成一个新的列表
# local是一个字典,字典里key(stack)是唯一标识,value是一个列表

11.Flask中多app应用如何编写?

请求进来时,可以根据URL的不同,交给不同的APP处理。蓝图也可以实现

    #app1 = Flask(‘app01‘)
    #app2 = Flask(‘app02‘)
    #@app1.route(‘/index‘)
    #@app2.route(‘/index2‘)

源码中在DispatcherMiddleware类里调用app2.__call__,

原理其实就是URL分割,然后将请求分发给指定的app。

之后app也按单app的流程走。就是从app.__call__走。

12.在Flask中实现WebSocket需要什么组件?

gevent-websocet

13.wtforms组件的作用?

定义:WTForms是一个支持多个web框架的form组件,主要用于对用户请求数据进行验证。

两种导入方式:

from wtforms import Form
from flask_wtf  import FlaskForm  需要设置csrf

安装:

pip3 install wtforms

作用:

  快速创建前端标签、文本校验:如django的ModelForm

14.Flask框架默认的session处理机制?

15.解释Flask框架中Local对象和threadinglocal对象的区别?

# a.threading.local
作用:为每个线程开辟一块空间进行数据存储(数据隔离)。

问题:自己通过字典创建一个类似于threading.local的东西。
storage = {
   4740: {val: 0},
   4732: {val: 1},
   4731: {val: 3},
   }

# b.自定义Local对象
作用:为每个线程(协程)开辟一块空间进行数据存储(数据隔离)。

class Local(object):
   def __init__(self):
      object.__setattr__(self, storage, {})
   def __setattr__(self, k, v):
      ident = get_ident()
      if ident in self.storage:
         self.storage[ident][k] = v
      else:
         self.storage[ident] = {k: v}
   def __getattr__(self, k):
      ident = get_ident()
      return self.storage[ident][k]
obj = Local()
def task(arg):
   obj.val = arg
   obj.xxx = arg
   print(obj.val)
for i in range(10):
   t = Thread(target=task, args=(i,))
   t.start()

16.SQLAlchemy中的session和scoped_session的区别?

# Session:
  由于无法提供线程共享功能,开发时要给每个线程都创建自己的session
  打印sesion可知他是sqlalchemy.orm.session.Session的对象
# scoped_session:
  为每个线程都创建一个session,实现支持线程安全
  在整个程序运行的过程当中,只存在唯一的一个session对象。
  创建方式:通过本地线程Threading.Local()
  # session=scoped_session(Session)
  创建唯一标识的方法(参考flask请求源码)

17.SQLAlchemy如何执行原生SQL?

# 使用execute方法直接操作SQL语句(导入create_engin、sessionmaker)
  engine=create_engine(‘mysql://root:pwd@127.0.0.1/database?charset=utf8‘)
  DB_Session = sessionmaker(bind=engine)
  session = DB_Session()
  session.execute(‘select * from table...;‘)

18.ORM的实现原理?

# ORM的实现基于以下三点

  映射类:描述数据库表结构,

  映射文件:指定数据库表和映射类之间的关系

  数据库配置文件:指定与数据库连接时需要的连接信息(数据库、登录用户名、密码or连接字符串)

19.DBUtils模块的作用?

# DBUtils是数据库连接池模块

使用模式:

  1、为每个线程创建一个连接,连接不可控,需要控制线程数

  2创建指定数量的连接在连接池,当线程访问的时候去取,不够了线程排队,直到有人释放*

两种写法:

  1.用静态方法装饰器,通过直接执行类的方法来连接使用数据库;

  2.通过实例化对象,通过对象调用方法使用语句;

20.SQLAlchemy中的如何为表设置引擎和字符编码?

sqlalchemy设置编码字符集,一定要在数据库访问的URL上增加‘charset=utf8‘,否则数据库的连接就不是‘utf8‘的编码格式

1. 设置引擎编码方式为utf8:

  engine = create_engine(‘mysql://root:root@localhost:3306/test2?charset=utf8‘,echo=True) 

2. 设置数据库表编码方式为utf8:

  engine = create_engine("mysql+pymysql://root:123456@127.0.0.1:3306/sqldb01?charset=utf8")  

class UserType(Base):
  __tablename__ = usertype i
  d = Column(Integer, primary_key=True)
  caption = Column(String(50), default=管理员)
   # 添加配置设置编码
  __table_args__ = {
     mysql_charset:utf8
  }

这样生成的SQL语句就自动设置数据表编码为utf8了,__table_args__还可设置存储引擎、外键约束等等信息。

21.SQLAlchemy中如何设置联合唯一索引

通过‘UniqueConstraint‘字段来设置联合唯一索引

__table_args=(UniqueConstraint(‘h_id‘,‘username‘,name=‘_h_username_uc‘))

#h_id和username组成联合唯一约束

 持续更新....

Flask------一些面试题

标签:服务器   __call__   nosql数据库   存在   middle   csrf   验证   gevent   task   

原文地址:https://www.cnblogs.com/Utopia-Clint/p/10824238.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!