Обертывание объектов расшириться/добавить функциональность при работе вокруг isinstance

Добрый вечер,

В вашем случае я бы сделал папку с вашими шаблонами.

Например:

templates
|- base.html
|- my_template.html
|- another_template.html

Включить

Решением является использование include:

Например, в вашем base.html у вас будет :

<html>

<head>

</head>

<body>
{% include ['my_template.html', 'another_template.html'] %}
</body>

</html>

Здесь мы включаем результаты рендеринга my_template.html и another_template.html в ваш шаблон base.html.

Вам нужно будет предоставить вашей функции рендеринга все параметры, необходимые для всех HTML-шаблонов, которые вы хотите рендерить.

Расширяет

С jinja2 вы также можете делать то, что вы хотите, используя емкость extends.

Итак, допустим, у вас есть шаблон base.html типа:

<html>

<head>

</head>

<body>
{% block core %}
{{ content }}
{% endblock %}

</body>

</html>

Здесь у нас есть блок с именем core.

Затем вы можете в другом шаблоне расширить базовый шаблон и заменить core block чем-то другим, например:

{% extends "base.html" %}
{% block core %}
<h1>Hello world</h1>
{% endblock %}

К сожалению, как вы можете видеть, это означает, что если вы хотите различные Кусочки HTML вам придется сделать несколько extends.

У вас может быть другой шаблон, который будет расширять предыдущий шаблон, который расширяет базовый.

Руководство

Последнее решение, которое, на мой взгляд, не рекомендуется, но ради него я буду раскрывать здесь:

Имеет base.html вида :

<html>

<head>

</head>

<body>
{% for html in list_html_to_render %}
{{ html }}
{% endfor %}
</body>

</html>

Тогда мы больше не используем Jinja2 в этом случае, но мы визуализируем каждый html, содержащийся в list_html_to_render, который передается в функцию рендеринга.

Надеюсь, это поможет.

Хорошего дня,

Мои наилучшие пожелания. [+1135]

5
задан Community 23 May 2017 в 12:19
поделиться

5 ответов

Если код библиотеки Вы зависите от использования isinstance и полагается на наследование, почему бы не следовать за этим маршрутом? Если Вы не можете изменить библиотеку затем, вероятно, лучше остаться согласовывающимся с ним.

Я также думаю, что существует законное использование для isinstance, и с введением абстрактных базовых классов в 2,6 это было официально подтверждено. Существуют ситуации где isinstance действительно правильное решение, в противоположность утиному вводу с hasattr или использование исключений.

Некоторые грязные опции, если по некоторым причинам Вы действительно не хотите использовать наследование:

  • Вы могли изменить только экземпляры класса при помощи методов экземпляра. С new.instancemethod Вы создаете методы обертки для своего экземпляра, который затем называет исходный метод определенным в исходном классе. Это, кажется, единственная опция, которая не изменяет исходный класс и не определяет новые классы.

Если можно изменить класс во времени выполнения существует много опций:

  • Используйте смешивание времени выполнения, т.е. просто добавьте класс к __base__ атрибут Вашего класса. Но это более используется для добавления определенной функциональности, не для неразборчивого обертывания, где Вы не знаете что потребность быть перенесенными.

  • Опции в ответе Dave (декораторы класса в Python> = 2.6 или Метаклассы).

Править: Для Вашего определенного примера я предполагаю только первые работы опции. Но я все еще рассмотрел бы альтернативу для создания a LogFoo или chosing в целом другое решение для чего-то определенного как вход.

2
ответ дан 15 December 2019 в 06:35
поделиться

Мой первый импульс состоял бы в том, чтобы попытаться исправить незаконный код, который использует isinstance. Иначе Вы просто распространяете его ошибки дизайна в к Вашему собственному дизайну. Какая-либо причина Вы не можете изменить его?

Править: Таким образом, Ваше выравнивание состоит в том, что Вы пишете код платформы/библиотеки, который Вы хотите, чтобы люди смогли использовать во всех случаях, даже если они хотят использовать isinstance?

Я думаю, что существует несколько вещей неправильно с этим:

  • Вы пытаетесь поддерживать поврежденную парадигму
  • Вы - тот, определяющий библиотеку и ее интерфейсы, это до пользователей для использования его правильно.
  • Нет никакого способа, которым можно возможно ожидать, что все плохое программирование пользователей библиотеки сделает, таким образом, это будет в значительной степени бесполезное усилие попытаться поддерживать плохие практики программирования

Я думаю, что Вы являетесь лучшими от написания идиоматичного, хорошо разработанный код. Хороший код (и плохой код) имеют тенденцию распространиться, поэтому сделайте Ваш примером. Надо надеяться, это приведет к полному увеличению качества кода. Хождение другим путем только продолжит качественное снижение.

0
ответ дан 15 December 2019 в 06:35
поделиться
0
ответ дан 15 December 2019 в 06:35
поделиться

Одна вещь иметь в виду состоит в том, что необходимо не обязательно использовать что-либо в базовом классе, если Вы идете путем наследования. Можно сделать тупиковый класс для наследования этому, не добавляет никакая конкретная реализация. Я несколько раз делал что-то вроде этого:

class Message(object):
     pass

class ClassToBeWrapped(object):
    #...

class MessageWithConcreteImplementation(Message):
    def __init__(self):
        self.x = ClassToBeWrapped()
    #... add concrete implementation here

x = MessageWithConcreteImplementation()
isinstance(x, Message)

Если необходимо наследоваться другим вещам, я предполагаю, что Вы могли бы столкнуться с некоторыми проблемами со множественным наследованием, но это должно быть довольно минимально, если Вы не обеспечиваете конкретной реализации.

Одна проблема, с которой я столкнулся, состоит в том что, когда я должен взаимодействовать через интерфейс с кодом, который использует isinstance антишаблон

Я соглашаюсь, что isinstance нужно избежать бы, если это возможно, но я не уверен, что назвал бы его антишаблоном. Существуют некоторые допустимые причины использовать isinstance. Например, существуют некоторые платформы передачи сообщений, которые используют это для определения сообщений. Например, если Вы получаете класс, который наследовался Завершению работы, пора подсистеме закрыться.

1
ответ дан 15 December 2019 в 06:35
поделиться

Если Вы пишете платформу, которая должна принять своего рода исходные данные от Ваших пользователей API, то нет никакой причины, о которой я могу думать для использования isinstance. Ужасный, как это могло бы быть, я всегда просто проверяю, чтобы видеть, обеспечивает ли это на самом деле интерфейс, я означаю использовать:

def foo(bar):
    if hasattr(bar, "baz") and hasattr(bar, "quux"):
        twiddle(bar.baz, bar.quux())
    elif hasattr(bar, "quuux"):
        etc...

И я также часто обеспечиваю хороший класс для наследования функциональности по умолчанию, если пользователь API хочет использовать ее:

class Bar:
    def baz(self):
        return self.quux("glu")

    def quux(self):
        raise NotImplemented
0
ответ дан 15 December 2019 в 06:35
поделиться
Другие вопросы по тегам:

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