我有这四个课程。
class Button(object):
def __init__(self):
pass
def invoke(self):
return self.button_dict
class Template(object):
def __init__(self):
pass
def message(self):
message = {'attachment': { 'type': self.type }}
message['attachment'].update(self.payload)
return message
class URLButton(Button):
def __init__(self, title, url):
self.button_dict = {
'type': 'web_url',
'title': title,
'url': url
}
class ButtonTemplate(Template):
def __init__(self, title, buttons):
if (not all(isinstance(button, Button) for button in buttons)):
raise ValueError('Invalid Buttons instances.')
self.type = 'button'
self.payload = {
'title': title,
'buttons': [
button.invoke() for button in buttons
]
}
呼叫...
ButtonList = [
URLButton('Test URL 1', 'http://example.com'),
URLButton('Test URL 2', 'http://example.com'),
'Invalid button here'
]
print(ButtonTemplate('Test', ButtonList).message())
我有很多课期待 Button 实例的列表,我想在下面的所有类中避免这种验证:
if (not all(isinstance(button, Button) for button in buttons)):
raise ValueError('Invalid Buttons instances.')
有没有办法强制参数成为实例列表? 什么是限制争论的更好方法?
工作代码段:https://repl.it/NJUv/2
答案 0 :(得分:1)
您可以使用装饰器修改每个类'__init__()
方法,从而减少锅炉板代码:
from functools import wraps
def validate_buttons_arg(func):
""" Method decorator that makes sure buttons argument is a list of Button
instances.
"""
@wraps(func)
def wrapper(self, title, buttons, *args, **kwargs):
if (not all(isinstance(button, Button) for button in buttons)):
raise ValueError('Invalid Buttons instances.')
return func(self, title, buttons, *args, **kwargs)
return wrapper
class ButtonTemplate(Template):
@validate_buttons_arg # Sample usage.
def __init__(self, title, buttons):
self.type = 'button'
self.payload = {
'title': title,
'buttons': [
button.invoke() for button in buttons
]
}
也可以使用类装饰器或元类自动执行类似于应用它们的每个类的__init__()
方法(而不是在它们之前手动添加@validate_button_arg
行。 def __init__
S)。