Naming Convention in Python

Post on 31-May-2015

1,935 views 0 download

Tags:

description

Talking about naming convention in Python, including topics discussed in “A Python Æsthetic” by Brandon Rhodes, and some personal note. NOTICE: Credits for example code snippets and various contents in this presentation (exclude the last part, starting from slide 27) fully go to Brandon Rhodes.

transcript

A Python Æsthetic

Video: http://pyvideo.org/video/1599/ Slides: http://rhodesmill.org/brandon/slides/2012-11-pyconca/

Video: http://pyvideo.org/video/1676/ Slides: http://rhodesmill.org/brandon/slides/2013-03-pycon/

Name the Ducks

• Well-factored Nouns

• Relentless Verbs

• Sin of Synecdoche

• Problem of Pluralization

Well-Factored Nouns

def main():! page = 'http://twitter.com/uranusjr/'! download_page(page)

Well-Factored Nouns

def main():! page = 'http://twitter.com/uranusjr/'! download_page(page)!!def download_page(page)! ... = client.get(page)

Well-Factored Nouns

def main():! page = 'http://twitter.com/uranusjr/'! download_page(page)!!def download_page(url)! page = client.get(url)

Well-Factored Nouns

def main():! page = 'http://twitter.com/uranusjr/'! download_page(page)!!def download_page(url):! page = client.get(url)! process_page(page)!!def process_page(page):! ... = page.content

Well-Factored Nouns

def main():! page = 'http://twitter.com/uranusjr/'! download_page(page)!!def download_page(url):! page = client.get(url)! process_page(page)!!def process_page(response):! page = response.content

Well-Factored Nouns

def main():! page = 'http://twitter.com/uranusjr/'! download_page(page)!!def download_page(url):! page = requests.get(url)! process_page(page)!!def process_page(response):! page = response.content

Well-Factored Nouns

def main():! url = 'http://twitter.com/uranusjr/'! download_page(url)!!def download_page(url):! response = requests.get(url)! process_page(response)!!def process_page(response):! page = response.content

Well-Factored Nouns

• Plan ahead (when you can)

• Refactor often

• Challenge yourself

Relentless Verbs

def database():! # What does this even do?!!def get_database():! # Gets an instance for me!!!def create_database():! # Creates a database and returns! # it for me!

Relentless Verbs

def database():! # What does this even do?!!def get_database():! # Gets an instance for me!!!def create_database():! # Creates a database and returns! # it for me!

Relentless Verbs

document.md5()! ! ! # Probably okay!!document.get_md5()!!document.calculate_md5()

[P]racticality beats purity.

[P]racticality beats purity.reversed(iterable)!!'a'.upper()!!

len(iterable)!!min(iterable)!

Relentless Verbs

• Functions act

• Verbose verbs can be dropped

• Practicality beats purity

Sin of Synecdoche

# In medialib.py:!def fetch_songs(urls):! ...!!# In songlib.py:!def fetch(urls):! ...

Sin of Synecdoche

# The caller has their choice:!!from songlib import fetch!fetch(...)!!# or:!!import songlib!songlib.fetch(...)

Sin of Synecdoche

• Be obvious

• Don’t repeat yourself

• Let users choose

Problem of Pluralization

>>> connections![<SQLConnection at 0xb72ff4d8>,! <SQLConnection at 0xb72ff4d0>,! <SQLConnection at 0xb72ff4f0>]!!>>> connections!{'master': <SQLConnection at 0xb72ff4d8>,! 'backup': <SQLConnection at 0xb72ff4f0>}

datum

data

datumdatum

datum

dataset

data

datumdatumdatum

data

datumdatumdatum

data

datum

datasets

datadatudatudatu

datadatudatudatu

datadatadatudatudatu

datadatudatudatu

datadataset

datadatudatudatu

datadatudatudatu

data

Anti-Plural

connection_set!connection_list!connection_dict!!def close_all(connection_seq):! ...!!def reset_all(connection_map):! ...

I still favor pluralsAnd documentation is always necessary.

Problem of Pluralization

• Plurals can be ambiguous

• There are only so many expressions

• Total anti-plural may be too much

My Problem

My Problem

def user_profile(request, username):! user = request.user! if user.is_authenticated:! if user.username == username:! # Show personal page! else:! # Show public page! else:! # Show page for anonymous user

My Problem

def user_profile(request, username):! user = request.user! if user.is_authenticated:! if user.username == username:! # Show personal page! else:! # Show public page! else:! # Show page for anonymous user

My Problem

>>> user.is_authenticated!<bound method User.is_authenticated of <User: admin>>

My Problem

def user_profile(request, username):! user = request.user! if user.is_authenticated():! if user.username == username:! # Show personal page! else:! # Show public page! else:! # Show page for anonymous user

Descriptive Boolean

# is + adjective = method!user.is_authenticated()!!!# No!!user.is_active!!# Clearly a noun.!user.activeness

Watch Out

# is + noun = variable?!>>> user.is_staff!True!!# But...!>>> '1'.isdigit!<built-in method isdigit of str object at 0x106fa63a0>

My Current Solution# is + anything = method!user.is_authenticated()!!!# WRONG!method.is_action = True!!# Considered correct (but ugly)!method.action_flag = True!!# Maybe use something else?!method.action_info = None

Python lacked booleans until 2.2.1

Maybe we can get away with it.

Similarly Problematic

# Makes more sense being a variable!request.url!!# Obviously needs processing. Okay.!document.md5()!!# ???!rectangle.left!rectangle.center

No Perfect Solution# Parentheses do not matter in Ruby!user.authenticated?!!# But things can get funky quickly!proc_obj = proc { user.authenticated? }!proc_obj.call!!# Python can be inconvenient!user.is_authenticated()!!# But obvious things stay obvious!func = user.is_authenticated!func()

FIRE QUESTIONS