鑑於這樣的:
stackoverflow.users['55562'].questions.unanswered()
我想把它轉換成如下:
http://api.stackoverflow.com/1.1/users/55562/questions/unanswered
我已經能夠實現這一目標,使用下面的類:
class SO(object):
def __init__(self,**kwargs):
self.base_url = kwargs.pop('base_url',[]) or 'http://api.stackoverflow.com/1.1'
self.uriparts = kwargs.pop('uriparts',[])
for k,v in kwargs.items():
setattr(self,k,v)
def __getattr__(self,key):
self.uriparts.append(key)
return self.__class__(**self.__dict__)
def __getitem__(self,key):
return self.__getattr__(key)
def __call__(self,**kwargs):
return "%s/%s"%(self.base_url,"/".join(self.uriparts))
if __name__ == '__main__':
print SO().abc.mno.ghi.jkl()
print SO().abc.mno['ghi'].jkl()
#prints the following
http://api.stackoverflow.com/1.1/abc/mno/ghi/jkl
http://api.stackoverflow.com/1.1/abc/mno/ghi/jkl
現在我的問題是我不能做這樣的事情:
stackoverflow = SO()
user1 = stackoverflow.users['55562']
user2 = stackoverflow.users['55462']
print user1.questions.unanswered
print user2.questions.unanswered
#prints the following
http://api.stackoverflow.com/1.1/users/55562/users/55462/questions/unanswered
http://api.stackoverflow.com/1.1/users/55562/users/55462/questions/unanswered/questions/unanswered
從本質上講,user1和user2是指同一SO
對象,因此它不能代表不同的用戶。
我一直在想任何指針這樣做將是有益的,因爲這種功能附加水平將使得API更有趣。
取代'__call__',如果實現'__str__'代替,因爲調用的語義是將對象轉換爲字符串,它可能是更優雅。這樣,您也可以直接打印「SO」對象。 – 2012-01-31 10:13:03
@FerdinandBeyer,不同意。該對象不是一個字符串,也不等同於一個字符串。爲打印添加'__str__'將使它看起來像一個字符串,但會導致混淆,因爲它不像其他目的的字符串。 – 2012-01-31 16:27:41
@WinstonEwert - 「添加'__str__'打印將使它看起來像一個字符串」 - 這是不正確的。 '__str__'用於獲取對象的字符串表示,而不是創建類似字符串的對象。它只用於'str()'和'print()'。這正是OP想要實現的 - 將他的對象轉換爲字符串。另見他的第二個例子,他忘記了__call__'的括號。 '__str__'在這裏會更加直觀。 – 2012-01-31 16:40:54