回答:
新しいスタイルのクラスのインスタンスのみがプロパティを持つことができます。Pythonに、そのようなインスタンスをモジュールであると信じ込ませることができます。sys.modules[thename] = theinstance。したがって、たとえば、m.pyモジュールファイルは次のようになります。
import sys
class _M(object):
    def __init__(self):
        self.c = 0
    def afunction(self):
        self.c += 1
        return self.c
    y = property(afunction)
sys.modules[__name__] = _M()types.ModuleTypeのその他の非常によく似た答えに示されているように、インスタンスのクラスを派生させることには特別な利点がありますか?
                    builtins.module、それ自体がtype(新しいスタイルのクラスの定義である)のインスタンスであるのインスタンスです。問題は、プロパティは、クラス、インスタンスではなく上になければならないということです:あなたがしなければf = Foo()、f.some_property = property(...)あなたは単純にモジュールに入れているかのように、それは同じように失敗します。解決策は、それをクラスに置くことですが、すべてのモジュールにプロパティを持たせたくないので、サブクラスにします(不明の回答を参照)。
                    globals()(キーはそのままにして値をにリセットするNone)の変更sys.modulesは、Python 2の問題です-Python 3.4は意図したとおりに動作します。Py2のクラスオブジェクトにアクセスする必要がある場合は、たとえばステートメントの_M._cls = _M直後に追加してclass(または他の名前空間に同等にスタッシュして)、それをself._cls必要とするメソッドのようにアクセスします(type(self)大丈夫かもしれませんが、のサブクラス化もしない場合_M) 。
                    これは、モジュールのすべての属性を適切に継承し、isinstance()によって正しく識別されるようにするためです。
import types
class MyModule(types.ModuleType):
    @property
    def y(self):
        return 5
>>> a=MyModule("test")
>>> a
<module 'test' (built-in)>
>>> a.y
5そして、これをsys.modulesに挿入できます:
sys.modules[__name__] = MyModule(__name__)  # remember to instantiate the class__file__、手動で定義する必要があるような他の属性も想定している可能性があります(2)クラスを含むモジュールで行われたインポートは、実行時に「見えない」など...
                    types.ModuleType、任意の(新しいスタイル)クラスが行います。継承したい特別なモジュール属性は何ですか?
                    __init__インスタンスのときにモジュール名を指定でき、を使用すると正しい動作が得られますisinstance。
                    PEP 562として Pythonで実装されています> = 3.7、今、私たちはこれを行うことができます
ファイル:module.py
def __getattr__(name):
    if name == 'y':
        return 3
    raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
other = 4使用法:
>>> import module
>>> module.y
3
>>> module.other
4
>>> module.nosuch
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "module.py", line 4, in __getattr__
    raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
AttributeError: module 'module' has no attribute 'nosuch'あなたは省略することに注意raise AttributeErrorして__getattr__機能、それが持つ機能の終了を意味しreturn None、その後、module.nosuchの値を取得しますNone。
ジョン・リンの答えに基づいて:
def module_property(func):
    """Decorator to turn module functions into properties.
    Function names must be prefixed with an underscore."""
    module = sys.modules[func.__module__]
    def base_getattr(name):
        raise AttributeError(
            f"module '{module.__name__}' has no attribute '{name}'")
    old_getattr = getattr(module, '__getattr__', base_getattr)
    def new_getattr(name):
        if f'_{name}' == func.__name__:
            return func()
        else:
            return old_getattr(name)
    module.__getattr__ = new_getattr
    return func使用方法(先頭のアンダースコアに注意)、中the_module.py:
@module_property
def _thing():
    return 'hello'次に:
import the_module
print(the_module.thing)  # prints 'hello'プロパティ化された関数を元の関数と区別するには、先頭のアンダースコアが必要です。識別子を再割り当てする方法を考えることができませんでした。デコレータの実行時に識別子がまだ割り当てられていないためです。
IDEはプロパティが存在することを認識せず、赤い波線が表示されることに注意してください。
@property def x(self): return self._xだと思いますdef thing()。そして、あなたはあなたの答えで「モジュールプロパティセッター」デコレーターも作成できますか?
                    def thing()提案を実装しようとしました。問題は、欠落している属性__getattr__に対してのみ呼び出されることです。ただし、@module_property def thing(): …実行後はthe_module.thingが定義されているため、getattrは呼び出されません。どういうわけかthing、デコレータに登録してから、それをモジュールの名前空間から削除する必要があります。Noneデコレータから戻ってみましたが、thingと定義されていNoneます。できるかもしれません@module_property def thing(): … del thingがthing()、関数として使用するよりも悪いことに
                    __getattribute__」もないようです。ありがとうございました。
                    典型的な使用例は次のとおりです。すべてのモジュールをクラスレイアウトに変換せずに、(巨大な)既存のモジュールをいくつかの(少数の)動的属性で強化します。残念ながら、次のような最も単純なモジュールクラスパッチsys.modules[__name__].__class__ = MyPropertyModule失敗しTypeError: __class__ assignment: only for heap typesます。そのため、モジュールの作成をやり直す必要があります。
このアプローチは、モジュールコードの上にプロローグをいくつか置くだけで、Pythonインポートフックなしでそれを行います。
# propertymodule.py
""" Module property example """
if '__orgmod__' not in globals():
    # constant prolog for having module properties / supports reload()
    print "PropertyModule stub execution", __name__
    import sys, types
    class PropertyModule(types.ModuleType):
        def __str__(self):
            return "<PropertyModule %r from %r>" % (self.__name__, self.__file__)
    modnew = PropertyModule(__name__, __doc__)
    modnew.__modclass__ = PropertyModule        
    modnew.__file__ = __file__
    modnew.__orgmod__ = sys.modules[__name__]
    sys.modules[__name__] = modnew
    exec sys._getframe().f_code in modnew.__dict__
else:
    # normal module code (usually vast) ..
    print "regular module execution"
    a = 7
    def get_dynval(module):
        return "property function returns %s in module %r" % (a * 4, module.__name__)    
    __modclass__.dynval = property(get_dynval)使用法:
>>> import propertymodule
PropertyModule stub execution propertymodule
regular module execution
>>> propertymodule.dynval
"property function returns 28 in module 'propertymodule'"
>>> reload(propertymodule)   # AFTER EDITS
regular module execution
<module 'propertymodule' from 'propertymodule.pyc'>
>>> propertymodule.dynval
"property function returns 36 in module 'propertymodule'"注:のようなfrom propertymodule import dynvalものはもちろん、凍結されたコピーを生成します-に対応しますdynval = someobject.dynval
proxy_toolsproxy_tools提供するために、パッケージの試み@module_property機能を。
それはとインストールします
pip install proxy_tools@Mareinの例を少し変更しthe_module.pyて、
from proxy_tools import module_property
@module_property
def thing():
    print(". ", end='')  # Prints ". " on each invocation
    return 'hello'今、別のスクリプトから、私はすることができます
import the_module
print(the_module.thing)
# . helloこの解決策には警告がないわけではありません。つまり、文字列でthe_module.thingはありません。これは、proxy_tools.Proxy文字列を模倣するように特別なメソッドがオーバーライドされたオブジェクトです。ポイントを説明するいくつかの基本的なテストはここにあります:
res = the_module.thing
# [No output!!! Evaluation doesn't occur yet.]
print(type(res))
# <class 'proxy_tools.Proxy'>
print(isinstance(res, str))
# False
print(res)
# . hello
print(res + " there")
# . hello there
print(isinstance(res + "", str))
# . True
print(res.split('e'))
# . ['h', 'llo']内部的には、元の関数は次の場所に保存され   the_module.thing._Proxy__localます。
print(res._Proxy__local)
# <function thing at 0x7f729c3bf680>正直なところ、モジュールにこの機能が組み込まれていない理由に困惑しています。問題の核心はそれthe_moduleがtypes.ModuleTypeクラスのインスタンスであると思います。「モジュールプロパティ」を設定すると、クラス自体ではなく、このクラスのインスタンスにプロパティを設定することになりますtypes.ModuleType。詳細については、この回答を参照してください。
types.ModuleType結果は素晴らしいものではありませんが、実際には次のようにプロパティを実装できます。組み込み型を直接変更することはできませんが、それらを呪うことはできます。
# python -m pip install forbiddenfruit
from forbiddenfruit import curse
from types import ModuleType
# curse has the same signature as setattr.
curse(ModuleType, "thing2", property(lambda module: f'hi from {module.__name__}'))これにより、すべてのモジュールに存在するプロパティが提供されます。すべてのモジュールで設定動作を壊すので、少し扱いにくいです。
import sys
print(sys.thing2)
# hi from sys
sys.thing2 = 5
# AttributeError: can't set attributecached_module_property事実__getattr__()は役に立ちます。(functools.cached_property達成することと同様)。
                    
__getattr__は、モジュールを参照してください。