The question arises because I’m trying to break a larger module with multiple classes into several smaller single-class modules.
In the large module, I used a variable with module scope to determine whether certain diagnostic functions would be defined. E.g.:
gTest = True # Generate diagnostic functions
def fTest( s, aWord):
But now, after “refactoring”, class
oTest is in a different module, and in that module,
gTest is undefined.
I can pass
gTest to the
oTest __init__(), and include the last three lines, above, in
__init__(), but this would make the
__init__() unwieldy and would put the
fTest() definition far from its natural position.
However, if I put the last three lines outside of
__init__(), then the
gTest value will be the initial class variable, not the instance variable set by
gTest = True
from mTest import oTest
x = oTest( gTest)
gTest = False
def __init__( s, aTest):
s.gTest = aTest # Sets instance varlable, not class variable
if gTest: # class variable (False), not instance variable (True)
def fTest( aWord):
(1) Am I using the right terminology and understanding the problem correctly?
(2) Is this a problem that a metaclass or “factory class” can solve?
This looks like an overcomplicated design. Could you please explain:
- What are the cases that
gTest = True and
gTest = False?
- Why do not you simply define the methods like
To retain your original functionality simply create a module for the
gTest variable and import it where needed.
gTest is called class attribute. It is a variable in the name scope of the class.
Also I would strongly recommend following the Python style:
CamelCase - classes
snake_case - variables, functions, methods
UPPER_CASE - constants
Thank you for responding.
What are the cases …?
gTest = True when debugging and
gTest = False when I no longer want the diagnostic code.
Because I don’t want the live version of the program cluttered with unused code.
I could go back to the original design, where everything is in a single module, but I am hoping to find a more elegant approach, one that gives me a chance to explore factory and meta classes, perhaps. I’m here to learn.
… the Python style
I like Python, in part because I value the freedom to code in a way that makes sense to me. A style is a fashion, and fashions evolve in response to input from non-conformists.
Python was designed as an interpreted language and in fact in most cases it is being executed as an interpreted language. It is just a detail that there is an automatic compilation to bytecode. The variable
gTest is a normal variable and setting it to
False does not change much.
It is normal that Python program contains a diagnostic code which normally display state and important events using the
logging module. I have never needed many or large functions/methods just for that.
- If you need to perform real tests (not run-time diagnostics) of your code, use
- You can also try to use a debugger.
- If large parts of the diagnostic code are the output formatting you can probably create a separate module / class just for the diagnostic output formatting. Then you can import the module conditionally. This would save a little bit more resources.
As I already wrote, to retain your desing, you can create a separate module for the variable
gTest and import it where needed. You can also set the variable from the command line parameters or a config file.
Are we talking about coding conventions / programming style? Programming normally involves a lot of cooperation in the form of getting information from the other people, analyzing code of other people, other people analyzing your code… For this the style is very important to avoid making all the effort much much bigger. One of the main ideas of Python is the readability of the code. The official style was designed to support the readability.
Of course for experiments, you can do anything but it does not seem that this is an experiment.
I found that I can use a function in
mTest to define the
oTest class. I pass the
gTest control variable to the function, and the function then selects what parts of the class to include. It’s a clean solution, and implementing it turned out to be much easier than I expected. This is the first time I’ve used a class factory – but it won’t be the last! Python is amazing.
Thank you again for your response. The program is indeed an experiment – a learning experiment. I am not working for a large corporation; I am simply developing a game for use by myself and my friends, and since I am the only programmer on this project, I am free to use a naming convention that makes sense to me. Moreover, when I read the Python tutorial, I do not find strict conformance to the recommended naming convention; instead, I find names like
I am glad that you have found a solution.
I suggested a parametrized class decorator. Later I realized it does not resolve your problem because you will need to have the deciding value in the same scope as the class definition... Anyway the original reply is hidden here.
Python has ways how to make your solution better. Instead of the special
mTest() function generating just a single class create a more generic re-usable class decorator. Then you can write something like:
I noticed that in my previous message I did not conclude my thought to an explicit statement. I wanted to say that you will have the methods anyway simply because it does not work like in compiled languages - e.g. like
#ifdef DEBUG in the C language.