直接インスタンス化できる場合Resource
は、それを実行して、パスとget
メソッドを直接貼り付けます。
from types import MethodType
book = Resource()
def get(self):
return aBook
book.get = MethodType(get, book)
book.path = path
これは、 and がメソッド内で使用されておらず、パスがクラスメソッドによって使用されていないこと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
もちろん、上記の 2 つのソリューションのいずれか、または Katrielalex の ABC の提案のいずれかを使用することをお勧めします。