Python

Table of contents

Child pages

Criticisms of Python

  • 2016.12.25 - ZenHack - Why Python Is Not My Favorite Language
    • Posted by Yang on his Twitter
    1. Lack of Encapsulation - Python makes it more annoying than it should be to wall things off behind an interface.
      • My summary: There's no protection / warning if you unknowingly try to use a private variable name (like "_bar") in a class you've created that subclasses another class that also uses that same private variable name.
    2. Weak Lambdas - Python's lambdas are seriously hamstrung: They can only be a single expression. No statements. Python has a bunch of built-in language features that would be totally obviated by adding a decent syntax for multi-statement lambdas.
      • The 'with' statement's functionality could be done very simply with lambdas, and wouldn't need to have special code within the core Python codebase to handle just that feature.
      • I couldn't make total sense of his decorator example. He seemed to be saying that, when using Flask, it's 'silly' to have to give your view-functions names when they're already uniquely defined by their string routes, and that in a language with strong support for lambdas you could just refer to the view-functions as unnamed/anonymous(?) functions, which would make the code easier to understand(?) / cleaner(?).
    3. Duck typing isn't very useful for production code - it is all too common in Python to either use nominal types anyway, or pass around mystery poultry.
      1. duck typing: If it looks like a duck and it quacks like a duck, it’s a duck. Or, as a more concrete example, if it’s got a next() method that returns the next element and raises StopIteration when you’re done, it’s an iterator.
      2. I didn't fully understand his example, but he seemed to be saying that, when using duck typing, you need to be sure to clearly document what your interfaces take as input and what they return, and once you're doing that much work, you might as well write the code in a slightly different way that'll do error checking for you, at which point there is no longer duck typing.
    4. Lack of a Type System - There are a few things that I really want a type system for: 1. Catching bugs earlier, 2. Refactoring, 3. Documentation

Learning resources

Information on miscellaneous tasks in Python

Creating a command-line program

Libraries

Articles / Videos

  • 2017.08.30 - OpenSource.com - 3 open source Python GUI frameworks
    • The command line offers many advantages—speed, remote access, reusability, scriptability, and control—which may be more important for your application's users than a graphical interface, and there are many libraries like Click, Cement, and Cliff that make it easier to design great command line programs.

Creating an executable (.exe)

  • 2018.01.25 - I was having an issue using cx_freeze with Python 3.5.2, and then when I tried using pyinstaller it crashed during the installation. I read something in a GitHub issue that led me to try running the same commands in a command prompt (rather than from within PyCharm's terminal), and amazingly, both cx_freeze and pyinstaller commands completed without errors. The cx_freeze executable didn't print my "hello world" message, but the pyinstaller executable did.

Misc tricks

  • Add logging to your code via a single decorator:
    • def run_with_logging(function):
          @wraps(function)
          def wrapped(*args, **kwargs):
              logging.basicConfig(filename='logs/' + function.__name__ + '.log', level=logging.DEBUG)
              logging.info('Starting at ' + str(datetime.now()))
              try:
                  function(*args, **kwargs)
              except Exception as e:
                  logging.exception(e)
                  traceback_message = traceback.format_exc()
                  send_an_email.send_email_with_error_message(traceback_message)
              logging.info('Finished at ' + str(datetime.now()))
          return wrapped
    • For your main function (that kicks everything off), just add "@run_with_logging" above the function declaration.
    • For anything you want logged in any submodules or subfunctions, just add a "logging.info(message)" to the code, and import "logging" into the module.
  • Add info to an AssertionError:
    • try:
          assert(thing_you_want_to_check_for)
      except AssertionError as e:
          e.args += ("Invalid company domain", company_domain)
          raise

Optimizing Python programs

  • Optimizing Python programs, PyPy to the rescue
    • 7:35 - First focus on optimizing the complexity of your code.
    • 12:30 - If switching to PyPy doesn't provide enough of a speed-up, you can use VMPROF to profile your program. He explains how to use it.
    • 16:06 - I stopped here.

Packages

PDFs

Testing

Misc learnings

  • The nice thing about the assertIn() function is that when it fails, it tells you what the values were. This is really helpful if you've got a loop where the same assertion is being tried against several values, because otherwise you wouldn't know what value you need to debug (unless you added extra try/except code, which would get messy to have everywhere).  The assertEqual function is useful for the same reason: if it fails, it not only tells you that the two things weren't equal (which is what a regular 'assert' statement would do), but it also tells you what the values of the two variables were.

Test-Driven Development

Virtualenvs