Python支持文字对象吗?

时间:2010-08-19 08:43:04

标签: python oop scala singleton object-literal

在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的方法是什么?

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的建议。