The approach I ended up using was to add an initialize
method to my gui_constants
module:
def initialize():
global heading_font
heading_font = wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD, face='LucidaGrande')
This approach requires that the user call this method before they use any of the constants defined in gui_constants
, but after the App
has been created. (Calling initialize
before the App
is ready results in a PyNoAppError, as in my question, and calling it too late gives an AttributeError when someone tries to access one of the not-yet-defined fonts.) The timing is not as tricky as I thought it would be, though; I call initialize
at the beginning of my App
subclass’s OnInit
method and that seems to work fine.
There were three other options mentioned (by Mike Driscoll and by VZ):
Store the font information in a tuple and pass this tuple to a
create_font
function each time a font is needed. For my taste this is too heavy; all users of the constants module need to know about the font-creation function, which should be a private implementation detail. It also adds a small amount of syntactic overhead all over the place.Use
eval
. The dangers ofeval
are well-known, and my personal policy is not to use it unless there’s no other way.Store the fonts as
FontInfo
objects and convert them toFont
objects later. This could be done by passing theFontInfo
to some constructor each time we want to use that font, as in option (1), or by constructing theFont
objects en masse, as I’m doing in my eventual solution. Using the former approach has the same objections I mentioned for item (1). Using the latter approach is basically what I’m doing, but with an extra layer of indirection.