🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

コンストラクタ

オブジェクト指向言語において、オブジェクトを生成時に呼び出され、データの初期化などを行なう関数・メソッドのことである。

Q&A

解決済

1回答

1351閲覧

クラス定義の書き方が解りません

BuhKeil

総合スコア34

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

コンストラクタ

オブジェクト指向言語において、オブジェクトを生成時に呼び出され、データの初期化などを行なう関数・メソッドのことである。

0グッド

0クリップ

投稿2021/03/26 14:46

やりたいこと

PythonでPILLOWライブラリを活用し、画像の生成をしたいです。
これまでは、画像の座標を直打ちして作成していたのですが、
拡張性・メンテナンス性の良いコードを書いてみたいと思い、クラス定義をしました。
しかし、作成したコードを実行すると、下記に示すようなエラーが発出します。
(→ 生じるエラー、を参照ください)

コンストラクタやメソッド内で使いたい変数なので、メソッドの外で宣言し、
コンストラクタや各メソッド内で
global font
と宣言すれば使えるのかと思ったのですが、正しく動作するコードを
どのように記述すればよいのか解りませんので、どなたかおわかりの方教えて下さい。

環境

  • Windows10 64bit
  • Python v3.8.3
  • PILLOWモジュール

コード

Python3

1from PIL import Image, ImageFont, ImageDraw 2 3class Component(): 4 5 # フォントの設定は他のメソッドでも使うので 6 # 共用させるために、この位置で宣言しました 7 # ------------------------------------------- 8 DefaultFontName = "KikaiChokokuJIS.otf" 9 DefaultFontSize = 40 10 font = ImageFont(DefaultFontName, DefaultFontSize) 11 12 def __init__(self, mode="RGB", size=(1920,1020),bkcolor=(203,0,0)): 13 global font 14 self.mode = mode 15 self.size = size 16 self.bkcolor = bkcolor 17 self.image = Image.new(self.mode,self.size,self.bkcolor) 18 self.draw = ImageDraw.Draw(self.image) 19 self.draw.text((300,500),datetime.datetime.now(),fill=(0,0,255),font=font) 20 self.image.save("templates/static/images/test.jpg", quality=85) 21 22 def DrawBox(self, pos_x,pos_y,fill=(128,128,128),outline=(50,50,50),title="Default"): 23 global font 24 self.pos_x = pos_x 25 self.pos_y = pos_y 26 self.title = title 27 28 self.draw.recangle((self.pos_x,self.pos_y,self.pos_x+300,self.pos_y+300), 29 fill=fill, 30 outline=outline, 31 width=5) 32 self.draw.text((self.pos_x,self.pos_y),self.title,fill=(255,255,255),font=font) 33 34 def Output(self): 35 code = str(random.random() * 1000) 36 return "test.jpg/?=" + code 37 38test_image = Component() 39print(test_image)

生じるエラー

Error

1class Component(): 2font = ImageFont(DefaultFontName, DefaultFontSize) 3TypeError: 'module' object is not callable

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

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

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

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

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

guest

回答1

0

ベストアンサー

多分ちゃんと動くであろうコードは下記になります。

from PIL import Image, ImageFont, ImageDraw import datetime import random class Component(): # フォントの設定は他のメソッドでも使うので # 共用させるために、この位置で宣言しました # ------------------------------------------- DefaultFontName = "KikaiChokokuJIS.otf" DefaultFontSize = 40 font = ImageFont.truetype(DefaultFontName, DefaultFontSize) def __init__(self, mode="RGB", size=(1920,1020),bkcolor=(203,0,0)): self.mode = mode self.size = size self.bkcolor = bkcolor self.image = Image.new(self.mode,self.size,self.bkcolor) self.draw = ImageDraw.Draw(self.image) self.image.save("templates/static/images/test.jpg", quality=85) self.image.save("test.jpg", quality=85) def DrawBox(self, pos_x,pos_y,fill=(128,128,128),outline=(50,50,50),title="Default"): self.pos_x = pos_x self.pos_y = pos_y self.title = title self.draw.rectangle((self.pos_x,self.pos_y,self.pos_x+300,self.pos_y+300), fill=fill, outline=outline, width=5) self.draw.text((self.pos_x,self.pos_y),self.title,fill=(255,255,255),font=Component.font) def Output(self): code = str(random.random() * 1000) return "test.jpg/?=" + code test_image = Component() test_image.DrawBox(10, 10) print(test_image.Output())

・クラス共通の変数(クラス変数)はglobalで指定するのはなく、「クラス名.メソッド名」でアクセスします。
(上の例だと、font=Component.fontとする)

・「recangle」 → 「rectangle」に修正。

・datetimeオブジェクトはそのままではdraw.text関数に渡せないので、strでキャストする等して文字列に変換する必要があります。
・下から2行目ですが、Componentを作るだけでは画像ファイルは生成されないため、
DrawBox()関数を呼び出す必要があります。
・print(test_image) とすると「<main.Component object at 0x00000XXXXXXXX>」と表示されてしまうため、(おそらく)意図する動作をさせるには、
print(test_image.Output())
賭する必要があります。

投稿2021/03/26 15:24

編集2021/03/26 23:55
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

BuhKeil

2021/03/26 23:24

アドバイスありがとうございます。 ご指摘頂いたように修正すると、__init__の中の8行目のところで、 NameError: name 'font' is not defined というエラーが出て止まってしまいます。
退会済みユーザー

退会済みユーザー

2021/03/26 23:54 編集

回答欄に全部のソースを記載しました。
BuhKeil

2021/03/28 11:21

qnoirさん、お返事が遅くなりました。 丁寧な解説ありがとうございます。 勉強不足でクラス名.メソッド名、の表記名は初めて知りました。 写経して自分で動作確認してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問