Discuss / Python / 对思考题的整理:3种方案

对思考题的整理:3种方案

Topic source

结合以上各位大神的讨论,整理出思考题解答的三种方案。

思考题:对带参数的api的动态链式调用

方案1: 添加def users(),将users('michael')视为1步

def users(self, username):
    return Chain('%s/%s' % (self._path, username))

方案2: 添加call , 将users('michael')视为2步

def __call__(self, param):
    return Chain('%s/%s' % (self._path, param))

方案3: 重写 getattr

def __getattr__(self, path):
    if path == 'users':
        return lambda x: Chain('%s/%s' % (self._path, 'user=' + x))
    return Chain('%s/%s' % (self._path, path))

可供检验的例子: print(Chain('abc').users('michael').repos) #各方案均可行 print(Chain('abc').users('michael').age(13).repos) #方案1不可行

总结: 个人认为方案3是最灵活的方法。

print(Chain('abc').users('michael').age(13).repos) 没有call函数的话,方案三好像也不行

虽然我也不知道API、SDK和URL是什么东西,不过老师的意思可能是根据调用的类属性来创建一个路径。 所以 Chain().users('michael').repos 期待输出的结果可能是 '/users/michael/repos' 所以方案一返回的应该是 'username/'+path 而不是 username。 至于方案三确实像菠菜兄说的一样,还要再判断一次 if path == 'age': 才可以,同样要返回 'users/' + x。 目前看来,从“把属性名和传入的参数都变成路径”这一点来说,方案二都可以做到;但偏偏这道题又出现在老师介绍call属性之前,所以老师目的可能是让我们想出方案一和三吧...

Reva龙舞

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

第二种方案从结果来看是不对的

Chain('abc').users('michael').repos /abc/users/michael/repos 实际应该输出 /abc/michael/repos

分析是因为,这种链式处理的顺序是

  1. Chain('abc').users
  2. Chain('abc').users('michael') #这里call了一次类(不是实例)
  3. Chain('abc').users('michael').repos 所以把users这个属性也带上了

第一和第三个方案结果上都是对的

DeepEndBoo

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

方案一和方案三都是可以解决users,但不能解决答主的age(13)。 方案二的call方法虽然不会报错,但是结果是abc/users/Michael/age/13/repos,并不是abc/Michael/13/repos这样子的。


  • 1

Reply