質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.44%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

580閲覧

【python-docx】プログラムは動くが、処理内容が分からない

chiaki0011

総合スコア1

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2023/05/11 04:47

編集2023/05/11 06:06

実現したいこと

wordのフッターを消すプログラムを作成しました。
動くのですが、なぜこれで動くのかがわかりません。
コードの解説をお願いしたいです。

前提

pythonで、wordのフッターを消すプログラムを実装しています。
python-docxで提供されているメソッドには目的にピンポイントに合うメソッドが無いようでしたので、インターネットでフッターを消すためのコードを調べました。
ソースコード上の、#↓このあたりの処理がわからない で書かれている箇所です。
これで確かに動くのですが、以下のことが理解できず困っています。
①paragraph._element 、paragraph._p とは何なのか
②paragraph._p = paragraph._element = None は何のために必要なのか
(この一行が無くても、フッターは消えます)
③なぜparagraph._p = paragraph._element = Noneだけではフッターが消えないのか。
paragraph._p = paragraph._element = Noneを実行することで、それぞれの要素の参照先アドレスが更新され、中身はnoneになることを確認しました。
であれば、このparagraph._p = paragraph._element = Noneだけ実装すればフッターは消えそうですが、このコードだけではフッターは消えません。

参照先アドレスは、print(id(paragraph._p))で、中身はprint(paragraph._p)でコンソールに出して調べました。

発生している問題・エラーメッセージ

ソースは動くが、仕組みが分からない。

該当のソースコード

python

1import os 2import docx 3from docx import Document 4import inspect 5 6#フッター削除対象フォルダ 7ROOT_PATH = 'XXXXXXXXXXXXXXXXXXXXXXXXXXX' 8 9def removeFooter(file_path): 10 11 document = docx.Document(file_path) 12 sections = document.sections 13 14 for section in sections: 15 sections_footer = section.footer 16 17 paragraphs = sections_footer.paragraphs 18 19 for paragraph in paragraphs: 20 21 #↓このあたりの処理がわからない 22 element = paragraph._element 23 element.getparent().remove(element) 24 paragraph._p = paragraph._element = None 25 #↑このあたりの処理がわからない 26 27 document.save(file_path) 28 29def process(path): 30 for pathname, dirnames, filenames in os.walk(path): 31 for filename in filenames: 32 if isDocx(filename): 33 removeFooter(os.path.join(pathname,filename)) 34 35def isDocx(filename): 36 return filename.endswith('.docx') 37 38def delete_paragraph(paragraph): 39 p = paragraph._element 40 p.getparent().remove(p) 41 paragraph._p = paragraph._element = None 42 43process(ROOT_PATH) 44 45### 試したこと 46各処理の前後で、参照しているアドレスとその中身を確認してみました。 47参照先アドレスは、print(id(paragraph._p))で、中身はprint(paragraph._p)でコンソールに出して調べました。 48 49------remove前------ 50------id------ 51element:      2143599308512 52paragraph._element:2143599308512 53paragraph._p:   2143599308512 54------中身------ 55element:      <CT_P '<w:p>' at 0x1f31879aee0> 56paragraph._element:<CT_P '<w:p>' at 0x1f31879aee0> 57paragraph._p:    <CT_P '<w:p>' at 0x1f31879aee0> 58 59------remove後------ 60------id------(remove前と変化なし) 61element:       2143599308512 62paragraph._element: 2143599308512 63paragraph._p: 2143599308512 64------中身------(remove前と変化なし) 65element: <CT_P '<w:p>' at 0x1f31879aee0> 66paragraph._element: <CT_P '<w:p>' at 0x1f31879aee0> 67paragraph._p: <CT_P '<w:p>' at 0x1f31879aee0> 68 69------paragraph._p = paragraph._element = None------(アドレスと中身が変わる) 70------id------ 71element: 2143599308512 72paragraph._element: 140711526034632 73paragraph._p: 140711526034632 74------中身------ 75element: <CT_P '<w:p>' at 0x1f31879aee0> 76paragraph._element: None 77paragraph._p: None 78 79### 補足情報(FW/ツールのバージョンなど) 80 81なし

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

meg_

2023/05/11 10:57

モジュールのドキュメントに説明は在りませんでしたか?
chiaki0011

2023/05/11 11:33

公式ドキュメントを参照し、getparent、_element、paragraph._pなどで検索をかけましたが、めぼしいものは出てきませんでした。getparentメソッドはヒットせず、残りはコンストラクタやメソッドなどから呼ばれているのはわかりましたが、その定義については探せませんでした。
meg_

2023/05/11 12:08

内部プロパティについてはドキュメントのリンクからソースを確認するしかないかと思います。
chiaki0011

2023/05/11 12:17

なるほど。先ほどGitHubにソース自体が公開されていることを知りました。 ただ、Pythonはおろか他の言語についてもほぼ知識がないので、私には読解が難しそうです。 パブリックメソッドで処理を追うのがやっとなので、もっと内部的なものになるとサッパリです。 知らないうちに初心者には難しい領域に手を出していたようですね。 ただ、わからないのにコピペしてツール動かすって気持ち悪いですよね。今後にも活かせないし。 宙ぶらりんにするのも気持ち悪いですが、一旦は諦めた方がいいのかもしれませんね。
guest

回答1

0

自己解決

本来直接操作すべきではないライブラリの内部を直接操作するようなコードであり、やはりコード自体があまりよろしくないということでクローズします。
本来は_elementや_pを直接コーディングしないし、その中身を意識しないのが正解。

投稿2023/05/11 15:45

chiaki0011

総合スコア1

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.44%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問