============================ 8.17 创建ä¸è°ƒç”¨init方法的实例 ============================ ---------- 问题 ---------- ä½ æƒ³åˆ›å»ºä¸€ä¸ªå®žä¾‹ï¼Œä½†æ˜¯å¸Œæœ›ç»•è¿‡æ‰§è¡Œ ``__init__()`` 方法。 ---------- 解决方案 ---------- å¯ä»¥é€šè¿‡ ``__new__()`` 方法创建一个未åˆå§‹åŒ–的实例。例如考虑如下这个类: .. code-block:: python class Date: def __init__(self, year, month, day): self.year = year self.month = month self.day = day 䏋颿¼”示如何ä¸è°ƒç”¨ ``__init__()`` 方法æ¥åˆ›å»ºè¿™ä¸ªDate实例: .. code-block:: python >>> d = Date.__new__(Date) >>> d <__main__.Date object at 0x1006716d0> >>> d.year Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Date' object has no attribute 'year' >>> 结果å¯ä»¥çœ‹åˆ°ï¼Œè¿™ä¸ªDate实例的属性year还ä¸å˜åœ¨ï¼Œæ‰€ä»¥ä½ éœ€è¦æ‰‹åЍåˆå§‹åŒ–: .. code-block:: python >>> data = {'year':2012, 'month':8, 'day':29} >>> for key, value in data.items(): ... setattr(d, key, value) ... >>> d.year 2012 >>> d.month 8 >>> ---------- 讨论 ---------- 当我们在ååºåˆ—对象或者实现æŸä¸ªç±»æ–¹æ³•æž„é€ å‡½æ•°æ—¶éœ€è¦ç»•过 ``__init__()`` 方法æ¥åˆ›å»ºå¯¹è±¡ã€‚ 例如,对于上é¢çš„Dateæ¥è®²ï¼Œæœ‰æ—¶å€™ä½ å¯èƒ½ä¼šåƒä¸‹é¢è¿™æ ·å®šä¹‰ä¸€ä¸ªæ–°çš„æž„é€ å‡½æ•° ``today()`` : .. code-block:: python from time import localtime class Date: def __init__(self, year, month, day): self.year = year self.month = month self.day = day @classmethod def today(cls): d = cls.__new__(cls) t = localtime() d.year = t.tm_year d.month = t.tm_mon d.day = t.tm_mday return d åŒæ ·ï¼Œåœ¨ä½ ååºåˆ—化JSONæ•°æ®æ—¶äº§ç”Ÿä¸€ä¸ªå¦‚下的å—典对象: .. code-block:: python data = { 'year': 2012, 'month': 8, 'day': 29 } å¦‚æžœä½ æƒ³å°†å®ƒè½¬æ¢æˆä¸€ä¸ªDate类型实例,å¯ä»¥ä½¿ç”¨ä¸Šé¢çš„æŠ€æœ¯ã€‚ å½“ä½ é€šè¿‡è¿™ç§éžå¸¸è§„æ–¹å¼æ¥åˆ›å»ºå®žä¾‹çš„æ—¶å€™ï¼Œæœ€å¥½ä¸è¦ç›´æŽ¥åŽ»è®¿é—®åº•å±‚å®žä¾‹å—典,除éžä½ 真的清楚所有细节。 å¦åˆ™çš„è¯ï¼Œå¦‚果这个类使用了 ``__slots__`` ã€properties ã€descriptors 或其他高级技术的时候代ç 就会失效。 而这时候使用 ``setattr()`` æ–¹æ³•ä¼šè®©ä½ çš„ä»£ç å˜å¾—æ›´åŠ é€šç”¨ã€‚