Discuss / Python / 讲真的,廖大在这里是不是手滑了??

讲真的,廖大在这里是不是手滑了??

Topic source

廖大的coroweb.py 里的 get_required_kw_args()用来扫描handler的参数。

def get_required_kw_args(fn):
    args = []
    params = inspect.signature(fn).parameters
    for name, param in params.items():
        if param.kind == inspect.Parameter.KEYWORD_ONLY and param.default == inspect.Parameter.empty:
            #handler 参数里只有KEYWORD_ONLY 才加入到args列表里。
            args.append(name)
    return tuple(args)

要把参数变成KEYWORD_ONLY,在handler里写函数的时候,是不是第一个参数得放一个' * 星号‘呢?


@get("/greeting/{name}")
async def greeting(*,name,request):#加了星号,name和request才是KEYWORD_ONLY,这样科学吗?
    logging.info('name : %s' % name)
    return web.Response(body=b"<h1>greeting</h1>"  )

假如我改成也扫描POSITIONAL_OR_KEYWORD类型的话,handler里边写起来就舒服多了。

def get_required_kw_args(fn):
    args = []
    params = inspect.signature(fn).parameters
    for name, param in params.items():
        if (param.kind == inspect.Parameter.KEYWORD_ONLY or param.kind==inspect.Parameter.POSITIONAL_OR_KEYWORD) and param.default == inspect.Parameter.empty:
            args.append(name)
    return tuple(args)

像这样

@get("/greeting/{name}")
async def greeting(name,request):
    logging.info('name : %s' % name)
    return web.Response(body=b"<h1>greeting</h1>"  )

大家有遇到这个问题吗?

@灰_手

灰_手

#3 Created at ... [Delete] [Delete and Lock User]
class RequestHandler(object):

    def __init__(self, app, fn):
        self._app = app
        self._func = fn
        self._has_request_arg = has_request_arg(fn)           # 是否有request参数
        self._has_var_kw_arg = has_var_kw_arg(fn)             # 是否有变长字典参数
        self._has_named_kw_args = has_named_kw_args(fn)       # 是否存在关键字参数
        self._named_kw_args = get_named_kw_args(fn)           # 所有关键字参数
        self._required_kw_args = get_required_kw_args(fn)     # 所有没有默认值的关键字参数

    async def __call__(self, request):
        kw = None
        # required_kw_args是named_kw_args的真子集,第三个条件多余
        if self._has_var_kw_arg or self._has_named_kw_args or self._required_kw_args:
            ...

        # 如果没有在GET或POST取得参数,直接把match_info的所有参数提取到kw
        if kw is None:
            kw = dict(**request.match_info)
        else:
            # 如果没有变长字典参数且有关键字参数,把所有关键字参数提取出来,忽略所有变长字典参数
            if not self._has_var_kw_arg and self._named_kw_args:
                ...
            # 把match_info的参数提取到kw,检查URL参数和HTTP方法得到的参数是否有重合
            for k, v in request.match_info.items():
                ...

        # 把request参数提取到kw
        if self._has_request_arg:
            kw['request'] = request
        # 检查没有默认值的关键字参数是否已赋值
        if self._required_kw_args:
            ...

        # 调用
        logging.info('call with args: %s' % str(kw))
        try:
            ...
        except APIError as e:
            ...

没有开发文档坑死人。

廖大的意思是想把URL参数和GET、POST方法得到的参数彻底分离。

  1. GET、POST方法的参数必需是KEYWORD_ONLY
  2. URL参数是POSITIONAL_OR_KEYWORD
  3. REQUEST参数要位于最后一个POSITIONAL_OR_KEYWORD之后的任何地方

http://www.qiangtaoli.com/bootstrap/?tag=Refactoring 的正确的写法是:

@get('/{template}/')
async def home(template, *, tag='', page='1', size='10'):
    # 这里会传进去两个参数:template=bootstrap, tag=Refactoring
   pass

如果有request参数,它可以放在template之后的任何地方,没有看错,就是这么随便。

灰_手

#4 Created at ... [Delete] [Delete and Lock User]

RequestHandler的逻辑多而混乱,建议拆分,强制参数类型感觉也不是很好,还不如写个开发文档来约束...orz

哈哈,果然按廖大的写法,参数列表里得加 * 。 这就有点浪了。

Day5往后是不是就没有难度了? 昨天看了看Day6,Day7 轻松愉快地就滑过去了。

灰_手

#6 Created at ... [Delete] [Delete and Lock User]

前端vue.js有大坑,目前2.0版都出来了,本教程还是0.1版的语法。 从严格意义来讲,廖大这项目并没有用上ajax,还是重新刷新加载,并没能善用vue.js的特性

幸亏有@灰_手 预警,我看到后边的时候直接从廖大仓库里拖了个vue.js来用。

为什么我从github上下载不到源码


  • 1

Reply