簡體   English   中英

來自 str 的總繼承(具有所有 str 構造函數)

[英]Total inheritance from str (having all str constructors)

我有以下類,我想將其表示為字符串(僅在__init__上設置body值之后):

class Component():
    body = ''
    template = None
    context = {}

    def __init__(self):
        if self.template:
            self.template = 'dashboards/' + self.template
            self.body += render_to_string(self.template, context = self.context)

    def __repr__(self):
        return str(self.body)

例如,如果我在下面打印一個Title類的實例..

class Title(Component):
    template = 'basic_components/title.html'
    defaults = {
        'text': 'Title',
    }

    def __init__(self, context=None):
        self.context = {**self.defaults, **(context or {})}
        super().__init__()

.. 我會得到一個字符串對象,由於父__repr__方法,這是我想要/期望的。

但是,我希望每個Component都表現得像一個字符串,而不僅僅是表示為一個字符串。 例如,如果我對兩個Title實例求和,我想要與對兩個str對象求和(concat)相同的行為

我可以轉到Component類並包含..

    def __add__(self, obj):
        return self.__repr__() + obj.__repr__()

..它會起作用。 但是,我想要大多數可用的字符串方法。 例如,我希望能夠選擇一個Title實例並使用它執行.join([..])

我嘗試像這樣在Component上繼承 str : class Component(str):但沒有成功。

此外,我試圖操縱__new__上構造Component ,但給我留下更加困惑,因為我需要self.body創建的字符串對象之前進行計算,並且__new__之前執行__init__ ..

我怎樣才能讓Component對象的行為完全像str對象的值body

編輯:

class Component(str):
    def __new__(cls, body=None, template=None, context=None):
        if not body:
            body = ''

        if template:
            template = 'dashboards/' + template
            body += render_to_string(template, context = context)

        return super().__new__(body)

class Title(Component):
    template = 'basic_components/title.html'
    defaults = {
        'text': 'Title',
    }

    def __init__(self, context=None):
        self.context = {**self.defaults, **(context or {})}
        super().__init__()

t = Title()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 8, in __new__
TypeError: str.__new__(X): X is not a type object (str)

我懷疑你想要類似的東西

class Component(str):
   
    def __new__(cls, value=None, *, template=None, context=None):
        if context is None:
            context = {}
        if template is not None:
            template = 'dashboards/' + template
            body = render_to_string(template, context)
        else:
            body = value

        return super().__new__(cls, value)

Component基本上是一個字符串,其值可以從位置參數中獲取或從兩個可選的關鍵字參數templatecontext構造。 在這種情況下,如果使用template則有效地忽略位置參數。

class Title(Component):
    
    def __new__(cls, value=None, **kwargs):
        kwargs.setdefault('context', {}).update(text='Title')
        kwargs['template'] = 'basic_components/title.html'
        return super().__new__(cls, value, **kwargs)

t = Title("title of the song")

Title只是一個子類,它在上下文中強制使用特定值並覆蓋任何顯式傳遞的template參數。

然后repr(t) == "'title of the song'" (就像任何其他str值一樣)。

所有“類屬性”已被默認參數值或硬編碼常量替換。 __new__用於代替__init__ ,因為您只能創建str新實例,而不能修改它們。 對象的值本身替換了body屬性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM