Tôi đã từng thực hiện Alex' trên Python 3.3, nhưng điều này treo thảm hại: mã
def __getattr__(self, name):
return globals()[name]
là không đúng vì một AttributeError
nên được nâng lên, không phải là một KeyError
. này bị rơi ngay dưới Python 3.3, vì có rất nhiều mẫn được thực hiện trong việc nhập khẩu, tìm kiếm các thuộc tính như __path__
, __loader__
, vv
Dưới đây là phiên bản mà chúng ta sử dụng hiện nay trong dự án của chúng tôi để cho phép nhập khẩu lười biếng trong một mô-đun.Các __init__
của các mô-đun bị trì hoãn cho đến khi truy cập thuộc tính đầu tiên rằng không có một cái tên đặc biệt:
""" config.py """
# lazy initialization of this module to avoid circular import.
# the trick is to replace this module by an instance!
# modelled after a post from Alex Martelli :-)
Lazy module variables--can it be done?
class _Sneaky(object):
def __init__(self, name):
self.module = sys.modules[name]
sys.modules[name] = self
self.initializing = True
def __getattr__(self, name):
# call module.__init__ after import introspection is done
if self.initializing and not name[:2] == '__' == name[-2:]:
self.initializing = False
__init__(self.module)
return getattr(self.module, name)
_Sneaky(__name__)
Module bây giờ cần xác định một init chức năng. Chức năng này có thể được sử dụng để nhập khẩu module có thể nhập mình:
def __init__(module):
...
# do something that imports config.py again
...
Mã này có thể được đưa vào mô-đun khác, và nó có thể được mở rộng với tính như trong ví dụ trên.
Có thể điều đó rất hữu ích cho ai đó.
Nguồn
2013-01-15 19:57:57
Điều đó hoàn toàn rực rỡ. Một bậc thầy tại nơi làm việc. – wbg