How do you implement “#ifdef” in python?

前端 未结 8 2032
广开言路
广开言路 2020-12-02 17:04

Programming in C I used to have code sections only used for debugging purposes (logging commands and the like). Those statements could be completely disabled fo

相关标签:
8条回答
  • It is important to understand that in Python def and class are two regular executable statements...

    import os
    
    if os.name == "posix":
        def foo(x):
            return x * x
    else:
        def foo(x):
            return x + 42
    ...
    

    so to do what you do with preprocessor in C and C++ you can use the the regular Python language.

    Python language is fundamentally different from C and C++ on this point because there exist no concept of "compile time" and the only two phases are "parse time" (when the source code is read in) and "run time" when the parsed code (normally mostly composed of definition statements but that is indeed arbitrary Python code) is executed.

    I am using the term "parse time" even if technically when the source code is read in the transformation is a full compilation to bytecode because the semantic of C and C++ compilation is different and for example the definition of a function happens during that phase (while instead it happens at runtime in Python).

    Even the equivalent of #include of C and C++ (that in Python is import) is a regular statement that is executed at run time and not at compile (parse) time so it can be placed inside a regular python if. Quite common is for example having an import inside a try block that will provide alternate definitions for some functions if a specific optional Python library is not present on the system.

    Finally note that in Python you can even create new functions and classes at runtime from scratch by the use of exec, not necessarily having them in your source code. You can also assemble those objects directly using code because classes and functions are indeed just regular objects (this is normally done only for classes, however).

    There are some tools that instead try to consider def and class definitions and import statements as "static", for example to do a static analysis of Python code to generate warnings on suspicious fragments or to create a self-contained deployable package that doesn't depend on having a specific Python installation on the system to run the program. All of them however need to be able to consider that Python is more dynamic than C or C++ in this area and they also allow adding exceptions for where the automatic analysis will fail.

    0 讨论(0)
  • 2020-12-02 17:34

    There is no direct equivalent that I'm aware of, so you might want to zoom-out and reconsider the problems that you used to solve using the preprocessor.

    If it's just diagnostic logging you're after then there is a comprehensive logging module which should cover everything you wanted and more.

    http://docs.python.org/library/logging.html

    What else do you use the preprocessor for? Test configurations? There's a config module for that.

    http://docs.python.org/library/configparser.html

    Anything else?

    0 讨论(0)
  • 2020-12-02 17:36

    If you are using #ifdef to check for variables that may have been defined in the scope above the current file, you can use exceptions. For example, I have scripts that I want to run differently from within ipython vs outside ipython (show plots vs save plots, for example). So I add

         ipy = False
         try:
            ipy = __IPYTHON__
         except NameError:
            pass
    

    This leaves me with a variable ipy, which tells me whether or not __IPYTHON__ was declared in a scope above my current script. This is the closest parallel I know of for an #ifdef function in Python.

    For ipython, this is a great solution. You could use similar constructions in other contexts, in which a calling script sets variable values and the inner scripts check accordingly. Whether or not this makes sense, of course, would depend on your specific use case.

    0 讨论(0)
  • 2020-12-02 17:40

    This can be achieved by passing command line argument as below:

    import sys
    
    my_macro = 0
    
    if(len(sys.argv) > 1):
        for x in sys.argv:
            if(x == "MACRO"):
                my_macro = 1
    
    if (my_macro == 1):
        controlled text
    

    Try running the following script and observe the results after this:

    python myscript.py MACRO
    

    Hope this helps.

    0 讨论(0)
  • 2020-12-02 17:41

    As far as I am aware, you have to use actual if statements. There is no preprocessor, so there is no analogue to preprocessor directives.

    Edit: Actually, it looks like the top answer to this question will be more illuminating: How would you do the equivalent of preprocessor directives in Python?

    Supposedly there is a special variable __debug__ which, when used with an if statement, will be evaluated once and then not evaluated again during execution.

    0 讨论(0)
  • 2020-12-02 17:42

    Here is an example that I use to distinguish between Python 2 & 3 for my Python Tk programs:

    
    import sys
    if sys.version_info[0] == 3:
        from tkinter import *
        from tkinter import ttk
    else:
        from Tkinter import *
        import ttk
    
    """ rest of your code """
    

    Hope that is a useful illustration.

    0 讨论(0)
提交回复
热议问题