python -docx library - Как расширить класс «Документ» - PullRequest
0 голосов
/ 06 августа 2020

В библиотеке python -docx объект Document создается с помощью конструктора fun c: docx.Document, который находится в файле docx.api

def Document(docx=None):
"""
Return a |Document| object loaded from *docx*, where *docx* can be
either a path to a ``.docx`` file (a string) or a file-like object. If
*docx* is missing or ``None``, the built-in default document "template"
is loaded.
"""
docx = _default_docx_path() if docx is None else docx
document_part = Package.open(docx).main_document_part
if document_part.content_type != CT.WML_DOCUMENT_MAIN:
    tmpl = "file '%s' is not a Word file, content type is '%s'"
    raise ValueError(tmpl % (docx, document_part.content_type))
return document_part.document

Но методы, которые можно применить к объекту находятся в файле docx.document.Document. Ниже приведен снимок

документ класса (ElementProxy): "" "документ WordprocessingML (WML).

Not intended to be constructed directly. Use :func:`docx.Document` to open or create
a document.
"""

__slots__ = ('_part', '__body')

def __init__(self, element, part):
    super(Document, self).__init__(element)
    self._part = part
    self.__body = None

def add_heading(self, text="", level=1):
    """Return a heading paragraph newly added to the end of the document.

    The heading paragraph will contain *text* and have its paragraph style
    determined by *level*. If *level* is 0, the style is set to `Title`. If *level*
    is 1 (or omitted), `Heading 1` is used. Otherwise the style is set to `Heading
    {level}`. Raises |ValueError| if *level* is outside the range 0-9.
    """
    if not 0 <= level <= 9:
        raise ValueError("level must be in range 0-9, got %d" % level)
    style = "Title" if level == 0 else "Heading %d" % level
    return self.add_paragraph(text, style)

def add_page_break(self):
    """Return newly |Paragraph| object containing only a page break."""
    paragraph = self.add_paragraph()
    paragraph.add_run().add_break(WD_BREAK.PAGE)
    return paragraph

def add_paragraph(self, text='', style=None):
    """
    Return a paragraph newly added to the end of the document, populated
    with *text* and having paragraph style *style*. *text* can contain
    tab (``\\t``) characters, which are converted to the appropriate XML
    form for a tab. *text* can also include newline (``\\n``) or carriage
    return (``\\r``) characters, each of which is converted to a line
    break.
    """
    return self._body.add_paragraph(text, style)

Я хочу понять - как я могу использовать методы класса Document на объект, созданный функцией - docx.Document. Что связывает их обоих?

Кроме того, как мне расширить класс Document с помощью нового метода и применить его к объекту, созданному функцией. Например, - ниже не работает

from docx.document import Document as doc1
class doc_new(doc1):
    def new_prop(self, q):
        self.name = q
        return self.name

document = Document()
x = document.new_prop("John")
print(x)

Ответы [ 2 ]

0 голосов
/ 07 августа 2020

Спасибо. Но как узнать, что объект документа создается docx.parts.document.DocumentPart. Я не могу найти это с помощью функции ниже.

'''
def Document(docx=None):
"""
Return a |Document| object loaded from *docx*, where *docx* can be
either a path to a ``.docx`` file (a string) or a file-like object. If
*docx* is missing or ``None``, the built-in default document "template"
is loaded.
"""
docx = _default_docx_path() if docx is None else docx
document_part = Package.open(docx).main_document_part
if document_part.content_type != CT.WML_DOCUMENT_MAIN:
    tmpl = "file '%s' is not a Word file, content type is '%s'"
    raise ValueError(tmpl % (docx, document_part.content_type))
return document_part.document

'''
0 голосов
/ 06 августа 2020

Объект Document, возвращаемый функцией docx.Document(), создается в методе .document() из docx.parts.document.DocumentPart здесь: https://github.com/python-openxml/python-docx/blob/master/docx/parts/document.py#L47 -L52

Таким образом, он создается, как любой другой объект Document, путем вызова класса с основным элементом XML документа.

С этого момента объект является экземпляром Document, у него есть все методы и свойства, определенные в классе docx.document.Document.

Создание этого объекта Document менее прямое, потому что это упрощает использование API в в большинстве случаев. Если бы он был прямым, пользователям пришлось бы выкопать элемент XML для себя, и многое стало бы намного сложнее, чем нужно для 99,9% пользователей.

Что касается расширения Функциональность Document у вас есть три основных варианта, которые я вижу:

  1. Создайте вилку python-pptx и отредактируйте класс docx.document.Document в соответствии с требованиями вместе с любыми подчиненными классами, такими как Paragraph et c.

  2. «Обернуть» (также известный как Compose ) объект документа с вашим собственным объектом, который добавляет свои собственные функции и передает другие вызовы к базовому объекту документа.

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

  3. Напишите функции, которые принимают документ в качестве своего первого аргумента и делают то, что вы хотите. Это своего рода «развоплощенный» метод объекта Document. Все методы Document - это функции, которые принимают объект Document в качестве первого параметра (self), поэтому вы можете делать большую часть того, что может делать метод таким образом.

    Это самый простой подход, На самом деле, способ, которым делает это большинство людей, и метод, который я рекомендую (и использую сам).

...