2013-10-15 109 views
4

我正在嘗試實現我想用來構建更高級別函數的get_date函數(例如,下面給出的get_payment_date)。這是我的代碼:如何覆蓋datetime.now()對象

from datetime import datetime 

def get_date(year=None, month=None, day=None): 
    '''Returns now, with the given parts overwritten''' 
    dt = datetime.now() 
    if not year is None : dt.year = year 
    if not month is None : dt.month = month 
    if not day is None : dt.day = day 
    return dt 

def get_payment_date(): 
    return get_date(day=15) 

print get_payment_date() 

但如果失敗:

AttributeError: attribute 'day' of 'datetime.date' objects is not writable 

我明白了。我該如何解決這個問題?我怎樣才能「覆蓋」now的某些部分?

+0

'get_date(month = 15)'這是什麼意思?這是15個月後? –

+0

Oooops,不好的例子。讓我糾正它。 – dangonfast

+0

你在找什麼?有沒有辦法超過寫日期時間,但是你可以嘗試生成(年,月,日)的新列表,然後生成新的日期時間 – Carlos

回答

7

datetime.datetimedatetime.date對象是不可變的。

你可以做dt = dt.replace(year = year)來獲得一個新的基於舊的日期時間對象。

你不一定想這樣做三次,但這樣的事情可能適合你:

+0

謝謝!這是我正在尋找的。我錯過了文檔:( – dangonfast

1

這就是我想要的東西(感謝史蒂夫·傑索普):

from datetime import datetime 

def get_date(year=None, month=None, day=None): 
    '''Returns now, with the given parts overwritten''' 
    dt = datetime.now() 
    kwargs = {} 
    if year : kwargs['year'] = year 
    if month : kwargs['month'] = month 
    if day : kwargs['day'] = day 
    if kwargs : return dt.replace(**kwargs) 
    else  : return dt 

def get_payment_date(): 
    return get_date(day=15) 

print get_payment_date() 

請注意,我需要構建一個kwargs,因爲dt.replace不接受None作爲year/month/day的值。另外,我刪除了is not None檢查,因爲0值意味着也沒有替換。

+0

僅供參考,'datetime.datetime.replace()'已經返回相同的對象,如果'kwargs'爲空,所以你不需要做那個測試,如果你不想。 –

+0

@SteveJessop:啊!你的意思是最後一次檢查嗎?但是我猜這個檢查比調用replace更少開銷,即使它什麼都不做? – dangonfast

+1

如果它什麼都不做,它可能會少一點工夫,而且是多花點功夫如果它調用'replace'(因爲'replace'再次執行相同的檢查),但我想到代碼量,而不是性能。 –