在Scala中,我可以定义一个抽象类,并使用对象实现它:
abstrac class Base {
def doSomething(x: Int): Int
}
object MySingletonAndLiteralObject extends Base {
override def doSomething(x: Int) = x*x
}
我在Python中的具体例子:
class Book(Resource):
path = "/book/{id}"
def get(request):
return aBook
继承在这里没有意义,因为没有两个类可以具有相同的path
。并且只需要一个实例,因此该类不会充当对象的蓝图。换句话说:Resource
(在我的示例中为Book
)此处不需要类,但需要基类来提供通用功能。
我想:
object Book(Resource):
path = "/book/{id}"
def get(request):
return aBook
Python 3的方法是什么?
答案 0 :(得分:6)
我相信这样一个对象的概念不是Python中典型的编码方式,但如果必须,那么下面的装饰器class_to_object
可以立即进行初始化。请注意,对象初始化的任何参数都必须通过装饰器传递:
def class_to_object(*args):
def c2obj(cls):
return cls(*args)
return c2obj
使用这个装饰我们得到
>>> @class_to_object(42)
... class K(object):
... def __init__(self, value):
... self.value = value
...
>>> K
<__main__.K object at 0x38f510>
>>> K.value
42
最终结果是你有一个与你的scala对象类似的对象K
,并且命名空间中没有类来初始化其他对象。
注意:为了迂腐,可以将对象K的类检索为K.__class__
,因此如果有人真的想要,可以初始化其他对象。在Python中,如果你真的想要,几乎总能找到解决方法。
答案 1 :(得分:2)
使用abc
(抽象基类):
import abc
class Resource( metaclass=abc.ABCMeta ):
@abc.abstractproperty
def path( self ):
...
return p
然后,需要从Resource
继承的任何内容来实现path
。请注意,path
实际上是在ABC中实现的;您可以使用super
访问此实施。
答案 2 :(得分:1)
如果您可以直接实例化Resource
,那么就这样做,并直接使用路径和get
方法。
from types import MethodType
book = Resource()
def get(self):
return aBook
book.get = MethodType(get, book)
book.path = path
这假设虽然在path
的{{1}}方法中未使用get
和__init__
,但该路径未被任何类方法使用得到你的关注。
如果您主要关心的是确保没有任何内容继承自Resource
非类,那么您可以使用此元类
Book
您可能希望用更合适的东西替换抛出的异常。如果你发现自己实例化很多,那真的才有意义。
如果这对你来说不够好并且你正在使用CPython,那么你总是可以尝试一下这个hackery:
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
由我的第一个上下文管理器成为可能。
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()
当然,我鼓励您使用上述两种解决方案之一或Katrielalex对ABC的建议。