Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

第3章LocalProxy的用法问题 #20

Closed
guyskk opened this issue Oct 11, 2016 · 7 comments
Closed

第3章LocalProxy的用法问题 #20

guyskk opened this issue Oct 11, 2016 · 7 comments

Comments

@guyskk
Copy link

guyskk commented Oct 11, 2016

https://github.com/dongweiming/web_develop/blob/master/chapter3/section4/app_with_local_proxy.py#L19

def get_current_user():

    users = User.query.all()
    return random.choice(users)

current_user = LocalProxy(get_current_user)

在一个请求中,每次获取current_user的属性都会重新执行一次get_current_user,导致一次请求会多次查询数据库。

也就是说这样的语句

name = current_user.name
email = current_user.email

会导致查询2次数据库。

因为current_user是一个代理对象,我将上述代码简化,如下:

Python 3.5.2 (default, Jun 28 2016, 08:46:01) 
[GCC 6.1.1 20160602] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from werkzeug.local import LocalProxy
>>> user = {}
>>> def get_current_user():
...     print("call")
...     return user
... 
>>> current_user = LocalProxy(get_current_user)
>>> current_user["name"] = "123"
call
>>> current_user["name"]
call
'123'
>>> current_user.__getitem__("name")
call
'123'
>>> 

每次获取current_user的属性都会打印出“call”,也就是执行一次get_current_user。

@dongweiming
Copy link
Owner

@guyskk 我懂了,对我这个例子来说是可以的,但是是错误的用法,晚上我再来。先谢了,去上班。

@dongweiming
Copy link
Owner

@guyskk
Copy link
Author

guyskk commented Oct 15, 2016

@dongweiming
用LocalStack实现有点复杂化了,在app.py的基础上加上这一句就可以了:

current_user = LocalProxy(lambda: g.user)

@dongweiming
Copy link
Owner

@guyskk g就是一个LocalProxy对象,直接用就好了 没必要再代理一次了

@guyskk
Copy link
Author

guyskk commented Oct 15, 2016

@dongweiming 也对,就是LocalStack这样实现太曲折了

@dongweiming
Copy link
Owner

我的例子类似于自己实现了一次 g ,展示了如何把user压入和推出栈

@guyskk
Copy link
Author

guyskk commented Oct 15, 2016

LocalProxy我是这样用,简化插件的编写(不需要写init_app方法),或者用于是不支持Flask工厂模式的库。不过这样会有一点性能损失。

@guyskk guyskk closed this as completed Oct 15, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants