Поддерживает ли Python что-то вроде литеральных объектов?

В 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

Наследование здесь не имеет смысла, так как никакие два класса не могут иметь одинаковый путь . И нужен только один экземпляр, чтобы класс не выступал в качестве схемы для объектов. Другими словами: здесь не нужен класс для Resource (в моем примере Book ), но базовый класс необходим для обеспечения общей функциональности.

Я бы хотел have:

object Book(Resource):

    path = "/book/{id}"

    def get(request):
        return aBook

Как бы это сделал Python 3?

11
задан deamon 19 August 2010 в 09:15
поделиться

2 ответа

Используйте декоратор для преобразования унаследованного класса в объект во время создания

Я считаю, что концепция такого объекта не является типичным способом кодирования в 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

Конечным результатом является то, что у вас есть объект K , похожий на ваш объект scala, и есть в пространстве имен нет класса для инициализации других объектов.

Примечание. Чтобы быть педантичным, класс объекта K может быть получен как K .__ class __ и, следовательно, другие объекты могут быть инициализированы, если кто-то действительно этого хочет. В Python почти всегда есть способ обойтись, если вы действительно этого хотите.

6
ответ дан 3 December 2019 в 10:24
поделиться

Используйте abc (абстрактный базовый класс):

import abc
class Resource( metaclass=abc.ABCMeta ):
    @abc.abstractproperty
    def path( self ):
        ...
        return p

Тогда для реализации пути требуется все, что наследуется от Resource . Обратите внимание, что путь фактически реализован в ABC; вы можете получить доступ к этой реализации с помощью super .

2
ответ дан 3 December 2019 в 10:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: