I think that “style” can be split into two distinct categories:
Visual clarity - Mainly about how things look, and that’s what PEP8 is all about: underscore_syntax vs camelCase, tabs vs spaces, import patterns, max line length, and so on. I agree with most of what PEP8 suggests, and I try to follow the segments I agree with, but in the great scheme of things, it’s really not that important when compared to the second category:
Linguistic elegance - This is the difficult part, because it’s all about what you write, and whether it makes clear sense in the given context. Visual clarity (PEP8) is about being able to read the words; Linguistic elegance is about being able to easily understand them. This category is truly the core of the programming discipline, because it touches on virtually everything: What you write depends heavily on the abstractions you devise, and they in turn define the overall architecture of the system as a whole, which then affects how you think (and therefore write) within it.
It’s truly a “Zen” kind of thing, and that’s probably why it has no “PEP8” equivalent - it’s almost ephemeral (although, that doesn’t stop people from writing books about the subject … but it’s still very hard to quantify good taste).
Anyway, here’s a few quick tips:
Avoid words that don’t add relevant meaning:
In the code you linked to, “TheSoundMachine” is the most egregious violation of this principle. “The” adds nothing to the description, and “Machine” is equally pointless. Virtually anything can be thought of as a “Machine”, but that doesn’t really tell us anything about what it does. “SoundManager” would be far more descriptive.
Names should describe fully:
“SoundManger” seems like a fine name, but looking at the implementation, we can see that it doesn’t just manage sounds. There is a clear distinction between sounds and music, and it seems like they’re both managed within this one class. So, we should think of a name that would encompass both. I think “AudioManager” would fit better in that case.
Avoid redundant labeling and needless variables:
The most obvious example in your code: “PATH_MUSIC = PATHS.PATH_MUSIC”. The module name implies that it’s a path, so you can just use “PATHS.MUSIC”.
Split overly-long lines into shorter expressions:
Look at line 167 …
Don’t repeat yourself, and avoid needless indirection:
Look at “playMusic” and “handle_music”: Pretty obvious red flag, don’t you think?
From a first look, I would say that “handle_music” is completely unnecessary; “playMusic” should create and play the handle, and “setMusicVolume” can simply set the volume on the handle, without going through VOLUME_BGMUSIC (no need for indirection there).
A function with more than 3 arguments is too complex:
“playOnFrame” …
Learn the alternatives, so you can choose better:
This:
dict = sound.sound_dict
factory = dict[random.choice(list(dict.keys()))]
Is better written like this:
factories = list(sound.sound_dict.values())
factory = random.choice(factories)
Avoid deep nesting, along with overly-long/messy functions:
“handle_sounds” … I think it’s incredibly convoluted, but I can’t really offer any concrete advice, because I honestly don’t know what you’re trying to do with that code.
A lot of it just seems unnecessary: If you want to play a sound, just generate a handle and play it. If you want to play a sound based on some animation frame, do the same thing, when the frame is played.
It seems like far too much management for something that should be relatively straightforward, so I would recommend rewriting the whole class from scratch, but with a better picture of what you really need, and how simple it could actually be.
Remember the KISS principle.