Python: best_practices[0]

Write better Python code in the future.


Let me share some snippets and learning moments in scripting and Python. Small things I just remembered or picked up recently. Here is the recollection of all this posts:


Visual Studio Code [color scheme: Night Owl (No Italics)]

FORMAT

The most political topic in Python is probably PEP8.

The Python formatting standard aka "Where to put a space?"


Avoid TypeErrors and create better formatted strings.

count = 3

# TypeError
# count + " nodes are selected."

# auto string convert
"{} nodes are selected.".format(count)


MULTI ASSIGNMENT

Assign multiple variables from a list.

GET file name
asset = "char_mike_RIG_v001"
asset_split = asset.split('_')

# single assignment
group   = asset_split[0]
asset   = asset_split[1]
task    = asset_split[2]
version = asset_split[3]

# multi assignment
group, asset, task, version = asset_split


FUNCTION NAMING

Naming is a crucial part of scripting since it is about readability and understanding. You wouldn't believe how neglected this topic is.


The rule is to create a "unique action":

create (action)


create_nodes (too generic)

create_read_nodes (yes: more unique)

create_read_nodes_by_paths (yes but long: very unique)


Describe a unique action.

# which nodes?
def nodes(paths):
    pass

# what does it do?
def read_nodes(paths):
    pass

# clear
def create_read_nodes(paths):
    pass

# crystal clear but long
def create_read_nodes_by_paths(paths):
    pass


EXCEPT PRINT

Have you ever heard of the "Zen of Python"? Now you did!


Using try-except means to catch exceptional situations. Make sure that everyone knows about that. The need to silence an error means often that your code structure needs an update.


"Errors should never pass silently." - Zen of Python

SILENCE!!! 
# Write code that doesn't need to silence an error.
try:
    'current frame: ' + 1001
except Exception as error:
    pass

# It is an exception and now I know
try:
    'current frame: ' + 1001
except Exception as error:
    print("ERROR: " + error.message)


EXCEPT FILES

Deciding when to try and catch or let the code fail so it doesn't break your data can be tricky. File handling especially has a variety of problems:


  • permissions

  • protected

  • disk full

  • in use

  • ...


But a must is to test if the paths exists beforehand as a minimum requirement.


Catch especially file handling

import shutil 

try:
    shutil.move(old_path, new_path)
except Exception as error:
    print("ERROR: Move files : " + error.message)
    print("  OLD: {}\n  NEW: {}".format(old_path, new_path))


NAMING LOOPS

Even a temporary loop variable needs a proper name.

A good practice is to use the plural name for the sequence and the singular form for the loop variable. Or would you call your child i, x, y or z?


Loop variables need proper names.

import maya.cmds as cmds

shaders = ['eyes_MTL', 'pants_MTL', 'shirt_MTL']

# pure cancer
for i in shaders:
    cmds.shadingNode('aiStandardSurface', asShader=True, name=i)

# clear
for shader in shaders:
    cmds.shadingNode('aiStandardSurface', asShader=True, name=shader)


FORMAT LOCAL

Spend some time with the locals, muchachos!

Format is a strong string function but with locals it is even similar to the f-String in Python 3. Guess what the f in f-String stands for. :)


Use local variables inside a string.

name = 'Alex'
age = 8

FORMAT
# using variables directly in the string
print("{name} is {age} years old.".format(**locals()))

# Python 3.7
# f-String
f"{name} is {age} years old."


90 CHARACTERS

"79, 80, 90, 100 or 120 characters per line ... why does it matter?!"

It actually matters when you need to scroll horizontally or compare two files.


Keep it limited but not religious.

79 characters [PEP8] 
90+/- characters [Raymond Hettinger]

# Forces to scroll horizontal
def set_project_context_in_shot( project='test_project', shot='s000_test', context=['sulley', 'mike', 'key_LGT_001', 'others']):
 pass

# Vertical scroll & compare view possible
def set_project_context_in_shot(project='test_project', 
                  shot='s000_test', 
                  context=['sulley', 'mike', 'key_LGT_001', 'others']):
 pass


BEST PRACTICE QUICKIE

Coding a script and writing a book are actually pretty similar.


Both use sophisticated languages to express themselves.

Both need strong characters to build a structure around and remember.

Both tell a story and go from A to Z (sometimes with twists and turns).

And both can take hundreds of lines to open a simple door;

while most of the time a few would suffice.


There are only benefits in consistently taking the better road.

# variable names
= 12
students = 12 # better

FORMATTING
# same line
assets = {'char' : ['mike', 'sulley'], 'props' : ['chair', 'table']}

# hanging indent
assets = {'char'  : ['mike', 'sulley'], 
 'props' : ['chair', 'table']} # better

# camelCase
thisIsAVeryLongNameToRead
# snake_case
this_is_a_very_long_name_to_read # better

You can find my most recent posts on LinkedIn and Twitter.

youtube.png

Be the first to know!

Get valuable resources and insides. Updates and articles.

*You can unsubscribe at any time.