Python支持文本对象之类的东西吗?

2024-10-01 22:28:25 发布

您现在位置:Python中文网/ 问答频道 /正文

在Scala中,我可以定义一个抽象类并用一个对象实现它:

abstrac class Base {
    def doSomething(x: Int): Int
}

object MySingletonAndLiteralObject extends Base {
    override def doSomething(x: Int) = x*x
}

我在Python中的具体示例:

^{pr2}$

继承在这里没有意义,因为没有两个类可以有相同的path。而且只需要一个实例,这样类就不会充当对象的蓝图。换句话说:Resource(在我的例子中,Book)不需要类,但是需要一个基类来提供公共功能。在

我想要:

object Book(Resource):

    path = "/book/{id}"

    def get(request):
        return aBook

python3的方法是什么?在


Tags: path对象base定义objectdef抽象类resource
3条回答

如果您可以直接实例化Resource,那么只需这样做,并直接将路径和get方法粘在一起。在

from types import MethodType

book = Resource()
def get(self):
    return aBook
book.get = MethodType(get, book)
book.path = path

虽然这是假设pathget没有在Resource__init__方法中使用,并且路径没有被任何不应该考虑的类方法使用。在

如果您的主要关注点是确保没有从Book非类继承,那么您可以使用这个元类

^{pr2}$

您可能希望用更合适的方法替换引发的异常。只有当你发现自己实例化了很多一次性实例时,这才有意义。在

如果这对你来说还不够好,而且你使用的是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      

当然,我鼓励你使用我的上述两种解决方案之一,或是凯特里亚莱克斯的ABC建议

使用decorator在创建时将继承的类转换为对象

我相信这样一个对象的概念并不是Python中典型的编码方式,但是如果必须这样做的话,下面用于立即初始化的装饰器class_to_object就可以做到了。初始化或任何参数都必须通过装饰对象传递:

def class_to_object(*args):
    def c2obj(cls):
        return cls(*args)
    return c2obj

使用这个装饰器

^{pr2}$

最终的结果是,您有一个与scala对象类似的对象K,并且名称空间中没有可用于初始化其他对象的类。在

注意:为了学究,对象K的类可以被检索为K.__class__,因此如果有人真的想初始化其他对象的话。在Python中,如果您真的想要的话,几乎总是有一种方法可以解决问题。在

使用^{}(抽象基类):

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

然后,需要从Resource继承的任何内容来实现path。注意,path实际上是在ABC中实现的;您可以使用super访问这个实现。在

相关问题 更多 >

    热门问题