pygame.error: font not initialized的解決及init()到底幹了什麼

耗子發表於2019-02-17

環境
Python3.6.8
pygame1.9.4

貼上報錯原始碼:

import pygame
my_font = pygame.font.SysFont(`arial`, 16)
my_font = pygame.font.Font(`my_font.ttf`, 16)

報錯內容:

Traceback (most recent call last):
  File "C:UsersHaoziHuangDesktoppygame44.py", line 6, in <module>
    my_font = pygame.font.SysFont(`arial`, 16)
  File "D:
jyjPythonpython3.6.8libsite-packagespygamesysfont.py", line 320, in SysFont
    return constructor(fontname, size, set_bold, set_italic)
  File "D:
jyjPythonpython3.6.8libsite-packagespygamesysfont.py", line 243, in font_constructor
    font = pygame.font.Font(fontpath, size)
pygame.error: font not initialized

不管先執行哪一個字型語句都會報錯,
當發生此錯誤時
這時我們該檢查
程式開始部分是否缺少pygame的初始化語句pygame.init()
而我們想問了, pygame.init()到底初始化個啥呀???
這個問題問得好!

以下內容轉載自:簡明現代魔法, 感謝大佬的分享

你究竟有(init)幾個好(子)妹(模)妹(塊)?

當我們在init()的時候,我們在幹什麼

init 這個單詞在我們用python進行物件導向開發的時候是跑不了的。理解python的__init__()其實就是和這裡的init()作用差不多。做的工作都是__初始化__.至於他在幹什麼,我的解釋是這樣的:

我們已經知道python有一個特殊的“工具包(模組)”叫pygame了。在我們要動手用它完成我們的想法之前,電腦這個強迫症需要我們檢查一遍,這個工具包是否完整,能否正常給我們提供幫助。而這個檢查的動作,就是pygame.init()

那麼init()實際上檢查了哪些東西呢?

這個其實也不難實驗。直接在shell裡面,我執行了這個函式:

>>> import pygame
>>> pygame.init()
(6, 0)

不明所以的,他給了我一個元組(6,0),我也很不理解,這個6和0分別代表什麼意思。所以查閱了pygame的官方文件

initialize all imported pygame modules

init() -> (numpass, numfail)

Initialize all imported pygame modules. No exceptions will be raised if a module fails, but the total number if successful and failed inits will be returned as a tuple. You can always initialize individual modules manually, but pygame.init() is a convenient way to get everything started. The init() functions for individual modules will raise exceptions when they fail.

You may want to initialize the different modules separately to speed up your program or to not use things your game does not.

It is safe to call this init() more than once: repeated calls will have no effect. This is true even if you have pygame.quit() all the modules.

初始化所有匯入的pygame模組。如果模組失敗,則不會引發異常,但如果成功且失敗的總數將作為元組返回。您可以隨時手動初始化單個模組,但pygame.init()初始化所有匯入的pygame模組是一種方便的方法來啟動所有內容。各個模組的init()函式會在失敗時引發異常。

您可能希望單獨初始化不同的模組以加速您的程式或不使用您的遊戲沒有的東西。

不止一次呼叫此init()是安全的:重複呼叫將不起作用。即使你有pygame.quit()所有模組也是如此。

關於init()的一個意外的實驗

我以前從來沒有深究過pygame.init()這個函式究竟init了哪些模組,僅僅在實踐的過程中知道,音訊播放和建立文字字型的時候,如果沒有init就會報錯。

今天我在安裝我的新的電腦環境的時候,因為不知道電腦的型號,所以並沒有特意去搜尋和安裝電腦對應的驅動。結果在安裝完python之後,安裝pygame(wheel也要安裝)之後,執行常規的測試函式pygame.init()返回的數字是(5,1)

排除問題的方法就是把已知可以init()的子模組都先執行掉。經過排查,發現pygame無法呼叫音效卡驅動。剩下的事情就好辦很多了,重新安裝一下音效卡驅動,重啟之後就可以正常init了。

但是在這個過程中,我可以得出比以前更加接近實際的一個結論:

pygame.init()在做的,其實就是檢查,電腦上一些需要的硬體呼叫介面、基礎功能是否有問題。如果有,他會在程式執行之前就反饋給你,方便你進行排查和規避。

說了這麼多,它到底init了哪些子模組

>>> import pygame
>>> pygame.init()
(6, 0)

>>> pygame.display.init()
>>> pygame.font.init()
>>> pygame.joystick.init()
>>> pygame.mixer.init()

>>> pygame.scrap.init()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
pygame.error: No display mode is set

>>> pygame.freetype.init()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module `pygame` has no attribute `freetype`
>>> pygame.midi.init()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module `pygame` has no attribute `midi`
>>> pygame.cdrom.init()

我把pygame官網上面的doc裡介紹的所有帶有init的子模組都執行了一遍。

其中midifreetype這兩個模組已經沒有了(吐槽一下官方的文件吧,都沒了還放著嘛)。

scrap初始化失敗是因為沒有視窗。這樣的話,其實已經有5個模組是被初始化了。但是scrap在沒有視窗的情況下會報錯,到底算不算一個init。還需要後面再仔細看看文件和原始碼吧。

That`s all!再次感謝這位大佬的分享!

附上官方文件

相關文章