问题描述
我想知道是否可以在执行 fetch('https://swapi.dev/api/people')
.then(response=>response.json())
.then(data=>console.log(data))
时在 Python 中自动创建实例方法。考虑这个代码示例,其中定义了一个类来处理一些音频文件格式元数据(异常处理和不相关的内容被省略):
__init__
现在:
__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)
,是否有一种 Pythonic 方法可以在创建实例时自动创建这些方法?
愚蠢的非工作示例只是为了解释我的意思:
mytags.set({'album':album,})
这将节省大量输入,最重要的是,如果 class Tags():
def __init__(self):
for tag in __tags__:
setattr(self,None)
setattr(self,'set_'+tag<reference to passed in argument>,<reference to the respective self.set() method>)
更新,则不需要任何更改。
解决方法
是的,您可以创建函数并将它们作为实例方法绑定到实例,例如,
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__
以便这些动态属性是制表符可完成的。