如果您可以Resource
直接实例化,您只需执行此操作并直接粘贴路径和get
方法。
from types import MethodType
book = Resource()
def get(self):
return aBook
book.get = MethodType(get, book)
book.path = path
这假设path
并且get
没有在__init__
方法中使用,Resource
并且路径没有被任何不应该引起您关注的类方法使用。
如果您主要关心的是确保没有任何东西从Book
非类继承,那么您可以使用这个元类
class Terminal(type):
classes = []
def __new__(meta, classname, bases, classdict):
if [cls for cls in meta.classes if cls in bases]:
raise TypeError("Can't Touch This")
cls = super(Terminal, meta).__new__(meta, classname, bases, classdict)
meta.classes.append(cls)
return cls
class Book(object):
__metaclass__ = Terminal
class PaperBackBook(Book):
pass
您可能想用更合适的东西替换抛出的异常。这只有在你发现自己实例化了很多一次性事件时才有意义。
如果这对你来说还不够好并且你正在使用 CPython,你总是可以尝试一些这样的骇客:
class Resource(object):
def __init__(self, value, location=1):
self.value = value
self.location = location
with Object('book', Resource, 1, location=2):
path = '/books/{id}'
def get(self):
aBook = 'abook'
return aBook
print book.path
print book.get()
我的第一个上下文管理器使这成为可能。
class Object(object):
def __init__(self, name, cls, *args, **kwargs):
self.cls = cls
self.name = name
self.args = args
self.kwargs = kwargs
def __enter__(self):
self.f_locals = copy.copy(sys._getframe(1).f_locals)
def __exit__(self, exc_type, exc_val, exc_tb):
class cls(self.cls):
pass
f_locals = sys._getframe(1).f_locals
new_items = [item for item in f_locals if item not in self.f_locals]
for item in new_items:
setattr(cls, item, f_locals[item])
del f_locals[item] # Keyser Soze the new names from the enclosing namespace
obj = cls(*self.args, **self.kwargs)
f_locals[self.name] = obj # and insert the new object
当然,我鼓励您使用上述两种解决方案之一或 Katrielalex 对 ABC 的建议。