77904


# やりたいこと

データクラスを使用した際、非推奨である旨を警告メッセージとして出力したいです。  
具体的には、データクラスのインスタンスを生成したときにメッセージを出力したいです。

# 試したこと

データクラス`Human`の`__init__`メソッドに、警告メッセージを出力する処理を追加したいです。  
以下のようなコードを書きました。

[code]

    import warnings
    from functools import wraps
    from typing import Optional
    from dataclasses import dataclass
    
    def _process_class(cls, deprecated_date: str, new_class_name: Optional[str] = None):
        def decorator(function):
            @wraps(function)
            def wrapped(*args, **kwargs):
                message = f"deprecated: {deprecated_date}以降に廃止します。"
                if new_class_name is not None:
                    message += f"替わりに'{new_class_name}'を使用してください。"
                warnings.warn(
                    message,
                    DeprecationWarning,
                )
    
            return wrapped
    
        cls.__init__ = decorator(cls.__init__)  # type: ignore
        return cls
    
    
    def deprecated_class(_cls=None, *, deprecated_date: str, new_class_name: Optional[str] = None):
        """クラスを非推奨にします。"""
    
        def wrap(cls):
            return _process_class(cls, deprecated_date=deprecated_date, new_class_name=new_class_name)
    
        if _cls is None:
            return wrap
        return wrap(_cls)
    
    
    @deprecated_class(deprecated_date="2021-09-01")
    @dataclass
    class Human:
        """非推奨なクラス"""
        name:str
        age:int
    
    
[/code]

しかし`Human`クラスのインスタンスを生成しようとすると、以下のエラーが出ました。

[code]

    Human("alice",18)
    
[/code]

[code]

    ...
    /usr/lib/python3.8/dataclasses.py in wrapper(self)
        366         repr_running.add(key)
        367         try:
    --> 368             result = user_function(self)
        369         finally:
        370             repr_running.discard(key)
    
    /usr/lib/python3.8/dataclasses.py in __repr__(self)
    
    AttributeError: 'Human' object has no attribute 'name'
    
    
[/code]

# 質問

エラーの原因は何で、どうすれば解決できるでしょうか？


CC BY-SA 4.0
2021-07-01T02:55:48.100
77895
2021-07-01T07:45:48.810
2021-07-01T07:29:12.310
19524
19524
question
python
データクラスのインスタンス生成時に警告メッセージを出したい


`wrapperd`関数に`function(*args, **kwargs)`が必要でした。

`wrapped`関数を以下の通り書き換えたら、期待通りの動きになりました。

[code]

            def wrapped(*args, **kwargs):
                message = f"deprecated: {deprecated_date}以降に廃止します。"
                if new_class_name is not None:
                    message += f"替わりに'{new_class_name}'を使用してください。"
                warnings.warn(
                    message,
                    DeprecationWarning,
                )
                return function(*args, **kwargs)
    
[/code]


CC BY-SA 4.0
2021-07-01T07:45:48.810
77904
2021-07-01T07:45:48.810
19524
77895
answer