1

When I develop C++ applications, I prefer to use macro functions for representing constant numbers. It enhances the readability of codes definitely.

I've searched to find the way to apply on python, but I couldn't find it.

If a similar function exists on python grammar, please tell me how to do it and if not exists on, tell me why it doesn't exist with regarding characteristic of python.

Thanks.

JongHyeon Yeo
  • 879
  • 1
  • 10
  • 18
  • 1
    What property of C++ Macros is it that you think is missing here? What problem are you trying to solve? – Stephen Rauch Jan 15 '18 at 06:33
  • Why not add them as global variables? But beware mutating them won't throw any error – chiragjn Jan 15 '18 at 06:34
  • I'm confused about how making constant numbers macros (especially macro *functions*) helps readability in C++, so I'm not sure how to replicate that in Python. – Daniel H Jan 15 '18 at 06:35
  • If you miss one liner of C++, Python has list / dictionary comprehensions, lambda functions, map, reduce etc. This link has some examples: http://codeblog.dhananjaynene.com/2011/06/10-python-one-liners-to-impress-your-friends/ Python is one of the easiest reader friendly programming language. To dive deep into increasing readability check PEP 8 (Style Guide for readability and long-term maintainability) documentation: https://www.python.org/dev/peps/pep-0008/ – arshovon Jan 15 '18 at 06:45
  • 1
    In C++ you should generally use `const` variables, not macros, to represent constant numbers. – Barmar Jan 15 '18 at 06:46
  • 2
    Possible duplicate of [How do I create a constant in Python?](https://stackoverflow.com/questions/2682745/how-do-i-create-a-constant-in-python) – Barmar Jan 15 '18 at 06:47
  • @Barmar Or better yet `constexpr`, if possible. – Daniel H Jan 15 '18 at 06:48
  • I agree that python is an easy language. But when I developed a big project on c++, I made a header file for managing constant values that have only macro. In this way, even a designer who don't read codes also can change these values by changing macro file easily. – JongHyeon Yeo Jan 15 '18 at 06:53

1 Answers1

1

You want a non-programmer to be able to alter these values, so it's a kind of configuration?

You can make a separate file with only assigments to global vars and then import that, or read and execute it.

Example (as used in https://github.com/QQuick/Opy):

#====================================================================================================
# General options
# All options have default value False
#====================================================================================================

obfuscate_strings = True        # Don't rely on this for sensitive information
obfuscated_name_tail = '_opy_'  # Will be added to all obfuscated names to avoid clashes with plain names
plain_marker = '_opy_'          # Strings or comments containing this marker will not be obfuscated
pep8_comments = True            # If True, only inline comments of the form <blank><blank>#<blank>
                                # will be recognized, allowing # to appear in strings as long as
                                # it doesn't have that particular form



#====================================================================================================
# Extensions of files that should be obfuscated
# Typically these are files containing Python source code
# Other files are just copied to the target directory
#====================================================================================================

source_extensions = '''
py
pyx
'''



#====================================================================================================
# Extensions of files that should neither be obfuscated nor copied to the target directory
# Typically these are .pyc files, which could easily be decompiled, breaking obfuscation
#====================================================================================================

skip_extensions = '''
pyc
'''



#====================================================================================================
# Fragments that, when occuring in the path of a file, will cause this file to be ignored
# In other words, such files will neither be ofuscated nor copied
# Use this to exclude complete directories from any processing by Opy
# N.B. Use forward slashes rather than backslashes, also on Windows!
#====================================================================================================

skip_path_fragments = '''
test_dummy
'''



#====================================================================================================
# Modules in sys.path containing identifiers that should not be obfuscated
# Typically these are installed standard or 3rd party modules of which you have no source code
# Use dotted names if needed, e.g. include both matplotlib and matplotlib.pyplot
#====================================================================================================

external_modules = '''
re
os
sys
errno
keyword
importlib
random
codecs
shutil
'''



#====================================================================================================
# Relative path + name of Python source files containing identifiers that should not be obfuscated
# Typically these are human readable settings files loaded and exec'ed at runtime by your program
# Do not use this facility for files that are imported, that's what external_modules is for
# Also don't use it to keep the original file name for your main module, that what plain_names is for
#====================================================================================================

plain_files = '''
opy_config.txt
'''



#====================================================================================================
# Extra identifiers and module names (as opposed to contents) that should not be obfuscated
# Probably at least the names of your main modules (so not their filenames) go here
# If e.g. your main module is in my_main_module.py, include my_main_module in plain_names
#====================================================================================================

plain_names = '''
opy
poly_walker_test
'''

It is read by the following code:

# =========== Read config file

    try:
        configFile = open (configFilePath)
    except Exception as exception:
        print (exception)
        printHelpAndExit (1)

    exec (configFile.read ())
    configFile.close ()

    def getConfig (parameter, default):
        try:
            return eval (parameter)
        except:
            return default

    obfuscateStrings = getConfig ('obfuscate_strings', False)
    asciiStrings = getConfig ('ascii_strings', False)
    obfuscatedNameTail = getConfig ('obfuscated_name_tail', '_{}_'.format (programName))
    plainMarker = getConfig ('plain_marker', '_{}_'.format (programName))
    pep8Comments = getConfig ('pep8_comments', True)
    sourceFileNameExtensionList = getConfig ('source_extensions.split ()', ['py', 'pyx'])
    skipFileNameExtensionList = getConfig ('skip_extensions.split ()', ['pyc'])
    skipPathFragmentList = getConfig ('skip_path_fragments.split ()', [])
    externalModuleNameList = getConfig ('external_modules.split ()', [])
    plainFileRelPathList = getConfig ('plain_files.split ()', [])
    extraPlainWordList = getConfig ('plain_names.split ()', [])
Jacques de Hooge
  • 6,750
  • 2
  • 28
  • 45