說明

2016-11-25 88 views
0

Python的dateutil.rrule模塊具有rrule對象與自定義__str__方法,以及它執行逆操作的方法rrulestr,即,重構rrule對象來自其字符串表示。下面是其使用的說明:說明

In [1]: from dateutil.rrule import * 

In [2]: my_rrule = rrule(DAILY, count=2) 

In [3]: list(my_rrule) 
Out[3]: 
[datetime.datetime(2016, 11, 25, 19, 58, 40), 
datetime.datetime(2016, 11, 26, 19, 58, 40)] 

In [4]: list(rrulestr(str(my_rrule))) 
Out[4]: 
[datetime.datetime(2016, 11, 25, 19, 58, 40), 
datetime.datetime(2016, 11, 26, 19, 58, 40)] 

我願做一個不同的對象類似的東西,所以我想了解這是RRULE的source code實現。下面是它包含一個「濃縮」摘錄:

class _rrulestr(object): 

    def _parse_rfc(self, s, 
        dtstart=None, 
        cache=False, 
        unfold=False, 
        forceset=False, 
        compatible=False, 
        ignoretz=False, 
        tzinfos=None): 
     global parser 

    def __call__(self, s, **kwargs): 
     return self._parse_rfc(s, **kwargs) 

rrulestr = _rrulestr() 

據我瞭解,爲_rrulestr類定義的__call__方法使得它基本上像一個功能。這種方法的優點是什麼?爲什麼不直接將rrulestr作爲函數定義?有人可以一步一步向我解釋這是如何工作的?

P.S.我也有模仿這種「可調用類」風格的問題。例如,如果我嘗試

#!/usr/bin/env python3.5 

class CallableClass(object): 
    def __call__(self, arg): 
     return arg 

print(CallableClass("Hello")) 

我得到一個TypeError

Traceback (most recent call last): 
    File "/home/kurt/Documents/Scratch/call_test.py", line 7, in <module> 
    print(CallableClass("Hello")) 
TypeError: object() takes no parameters 

,但我沒有看到這個例子是如何從_rrulestr如此不同?

回答

1

「可調用類」的要點是它是可調用的實例。當然,任何類都可以調用,因爲調用一個類給你一個實例;但是定義__call__方法意味着生成的實例也是可調用的。

所以,你的代碼應該是:

print(CallableClass()("Hello")) 

正如你所看到的,rrule模塊定義其在最後的實例:rrulestr = _rrulestr() - 這是你調用該對象。