Python 使用json键定义的抽象方法创建ABC
假设我有一个json文件,如下所示:Python 使用json键定义的抽象方法创建ABC,python,json,python-3.x,abc,Python,Json,Python 3.x,Abc,假设我有一个json文件,如下所示: { "foo": ["hi", "there"], "bar": ["nothing"] } 我想创建一个抽象基类(ABC),其中抽象方法的名称是上面json的键,即: from abc import ABCMeta, abstractmethod class MyABC(metaclass=ABCMeta): @abstractmethod def foo(self): pass @abstr
{
"foo": ["hi", "there"],
"bar": ["nothing"]
}
我想创建一个抽象基类(ABC),其中抽象方法的名称是上面json的键,即:
from abc import ABCMeta, abstractmethod
class MyABC(metaclass=ABCMeta):
@abstractmethod
def foo(self):
pass
@abstractmethod
def bar(self):
pass
问题是json文件实际上有很多键。我想知道是否有这样的方法:
import json
with open("the_json.json") as f:
the_json = json.load(f)
class MyABC(metaclass=ABCMeta):
# for k in the_json.keys():
# create abstract method k
感谢评论中的建议,但不知怎么的,它并没有像预期的那样起作用。以下是我尝试过的:
class MyABC(metaclass=ABCMeta):
pass
def f(self):
pass
setattr(MyABC, "foo", abstractmethod(f))
# I also tried
# setattr(MyABC, "foo", abstractmethod(lambda self: ...))
# Try to define another class that inherits MyABC
class MyClass(MyABC):
pass
c = MyClass()
# Now this should trigger TypeError but it doesn't
# I can even call c.foo() without getting any errors
这可能会起作用:
从abc导入ABCMeta,abstractmethod
将open(“the_json.json”)作为f:
_json=json.load(f)
类MyABC(元类=ABCMeta):
def func(自我):
通过
对于_json中的k:
局部变量()[k]=abstractmethod(func)
#必须删除属性“func”
#否则,它将成为MyABC中的附加抽象方法
delattr(MyABC,“func”)
delattr(MyABC,“f”)
delattr(MyABC,“k”)
类别MyClass(MyABC):
通过
MyClass()
#TypeError:无法使用抽象方法bar、foo实例化抽象类MyClass
如果您试图实例化MyABC,或者MyABC的子类没有实现抽象方法,它将正确地抛出错误。这可能会起作用:
从abc导入ABCMeta,abstractmethod
将open(“the_json.json”)作为f:
_json=json.load(f)
类MyABC(元类=ABCMeta):
def func(自我):
通过
对于_json中的k:
局部变量()[k]=abstractmethod(func)
#必须删除属性“func”
#否则,它将成为MyABC中的附加抽象方法
delattr(MyABC,“func”)
delattr(MyABC,“f”)
delattr(MyABC,“k”)
类别MyClass(MyABC):
通过
MyClass()
#TypeError:无法使用抽象方法bar、foo实例化抽象类MyClass
如果您试图实例化MyABC,或者MyABC的一个子类没有实现抽象方法,它将正确地抛出一个错误。@Nair我想说的更多是@ChatterOne的副本,我同意链接和它与我提到的非常相似。装饰器的工作方式是在函数上调用它
func=decorator(函数)
与@decorator def func():pass
相同。通过调用abstractmethod(method)
使用setattr
。尝试…
而不是pass
..
被称为省略号
@DiptangsuGoswami谢谢你,但这并不像预期的那样有效。你能看看我上面的编辑并告诉我我做错了什么吗?@Nair我想说的更多的是@ChatterOne的副本,我同意链接和它与我提到的非常相似。装饰师的工作方式是在函数上调用它func=decorator(函数)
与@decorator def func():pass
相同。通过调用abstractmethod(method)
使用setattr
。尝试…
而不是pass
..
被称为省略号
@DiptangsuGoswami谢谢你,但这并不像预期的那样有效。你能看看我上面的编辑并告诉我我做错了什么吗?谢谢。但正如我上面的编辑所示,如果您定义了一个新类,如classmyclass(MyABC):pass
,则可以启动MyClass()
,而不会触发任何错误。这不应该是正确的,对吗?按照你的说法,为什么会触发错误?你真的希望它触发一个错误,还是你只是在期待它?正如所指出的,应该有TypeError
,因为MyClass
有一些尚未实现的方法。“abc模块还定义了一个新的装饰器,@abstractmethod
,用于声明抽象方法。一个至少包含一个用这个装饰器声明的方法但尚未被重写的类不能被实例化。”嘿@ytu,我用一个新的解决方案编辑了我的答案,我认为它可以按照您的意愿工作。如果是的话,你能把它标记为接受吗?谢谢。但正如我上面的编辑所示,如果您定义了一个新类,如classmyclass(MyABC):pass
,则可以启动MyClass()
,而不会触发任何错误。这不应该是正确的,对吗?按照你的说法,为什么会触发错误?你真的希望它触发一个错误,还是你只是在期待它?正如所指出的,应该有TypeError
,因为MyClass
有一些尚未实现的方法。“abc模块还定义了一个新的装饰器,@abstractmethod
,用于声明抽象方法。一个至少包含一个用这个装饰器声明的方法但尚未被重写的类不能被实例化。”嘿@ytu,我用一个新的解决方案编辑了我的答案,我认为它可以按照您的意愿工作。如果是的话,你能把它标记为接受吗?