【问题标题】:Can Python instance methods be automatically defined at __init__ time?Python 实例方法可以在 __init__ 时间自动定义吗?
【发布时间】:2021-04-07 21:34:29
【问题描述】:

我想知道在执行__init__ 时是否可以在Python 中自动创建实例方法。考虑这个代码示例,其中定义了一个类来处理一些音频文件格式元数据(异常处理和不相关的东西被省略):

__tags__ = ['album', 'artist', 'date', 'genre', 'title', 'tracknumber']

class Tags():
    def __init__(self):
        for tag in __tags__:
            setattr(self, tag, None)

    def print(self):
        for k, v in self.__dict__.items():
            if v:
                print('{}: {}'.format(k, str(v)))

    def get(self, *pa):
        ret = [getattr(k) for k in pa if k in __tags__]
        return ret if len(pa)>1 else ret[0]

    def set(self, **ka):
        for k, v in ka.items():
            if k in __tags__:
                setattr(self, k, str(v))

现在:

    mytags = Tags()
    mytags.set(album='The best of Ennio Morricone', artist='Various Artists')
    mytags.print()
    print()
    mytags.set(genre='Soundtrack', tracknumber=3)
    mytags.set(title='Secret Of The Sahara')
    mytags.print()
    print(mytags.album is mytags.get('album'))

打印:

album: The best of Ennio Morricone
artist: Various Artists

album: The best of Ennio Morricone
artist: Various Artists
genre: Soundtrack
title: Secret Of The Sahara
tracknumber: 3
True

假设现在我想为每个标签添加get_<tag>/set_<tag> 方法,即mytags.set_album(album)title=mytags.get_title()。鉴于mytags.set_album(album) 转换为mytags.set({'album':album,}),是否有一种pythonic 方法可以在创建实例时自动创建这些方法? 愚蠢的非工作示例只是为了解释我的意思:

    class Tags():
        def __init__(self):
            for tag in __tags__:
                setattr(self, tag, None)
                setattr(self, 'set_'+tag<reference to passed in argument>,
                        <reference to the respective self.set() method>)

这将节省大量输入,最重要的是,如果 __tags__ 被更新,它不需要任何更改。

【问题讨论】:

    标签: python metaprogramming instance-methods python-class


    【解决方案1】:

    是的,您可以创建函数并将它们作为实例方法绑定到实例,例如,

    def __init__(...):
        tag = "album"
        def whatever_func(self, gettag=tag):
           return getattr(self, gettag)
        setattr(self, f"get_{tag}", whatever_func.__get__(self))
    

    不过,它并不漂亮,对吧?我认为你最好定义一个__getattr__ 来处理任何未定义的属性访问;您还应该定义 __dir__ 以便这些动态属性是制表符可完成的。

    【讨论】:

      猜你喜欢
      • 2019-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-20
      相关资源
      最近更新 更多