Code Like Pythonista
Beautifully made PPT.
Ref. http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html
Image ref : https://pixabay.com/ko/ and https://morguefile.com/
licensed under a Creative Commons Attribution/Share-Alike (BY-SA) license.
2. The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
3. The Zen of Python, by Tim Peters
아름다움이 추함보다 좋다.
명시가 암시보다 좋다.
단순함이 복잡함보다 좋다.
복잡함이 꼬인 것보다 좋다.
수평이 계층보다 좋다.
여유로운 것이 밀집한 것보다 좋다.
가독성은 중요하다.
특별한 경우라는 것은 규칙을 어겨야 할 정도로 특별한 것이 아니다.
허나 실용성은 순수성에 우선한다.
오류 앞에서 절대 침묵하지 말지어다.
명시적으로 오류를 감추려는 의도가 아니라면.
모호함을 앞에 두고, 이를 유추하겠다는 유혹을 버려라.
어떤 일에든 명확한 - 바람직하며 유일한 - 방법이 존재한다.
비록 그대가 우둔하여 그 방법이 처음에는 명확해 보이지 않을지라도.
지금 하는게 아예 안하는 것보다 낫다.
아예 안하는 것이 지금 *당장*보다 나을 때도 있지만.
구현 결과를 설명하기 어렵다면, 그 아이디어는 나쁘다.
구현 결과를 설명하기 쉽다면, 그 아이디어는 좋은 아이디어일 수 있다.
네임스페이스는 대박 좋은 아이디어다 -- 마구 남용해라!
5. • 4 spaces per indentation level.
• No hard tabs.
• Never mix tabs and spaces.
• One blank line between functions.
• Two blank lines between classes.
• Add a space after "," in dicts, lists, tuples, ETC, but not before.
• Put spaces around assignments & comparisons
•except in argument lists
• No spaces just inside parentheses or just before argument lists.
• No spaces just inside docstrings.
6. •joined_lower for functions, methods, attributes
•joined_lower or ALL_CAPS for constants
•StudlyCaps for classes
•camelCase only to conform to pre-existing conventions
•Attributes: interface, _internal, __private
But try to avoid the __private form. I never use it.
Trust me. If you use it, you WILL regret it later.
__private is NOT like to C++/Java private
7. •Keep lines below 80 characters in length
•Use implied line continuation inside parentheses/brackets/braces:
•Use backslashes as a last resort:
•Adjacent literal strings are concatenated by the parser
•Any type of quoting can be used
•r is a raw string (Backslashes are not evaluated as escapes in raw strings.)
def __init__(self, first, second, third,
fourth, fifth, sixth):
output = (first + second + third
+ fourth + fifth + sixth)
VeryLong.left_hand_side
= even_longer.right_hand_side()
>>> print 't' r'//' """o"""
t//o
8. •Multiple statements on one line are a cardinal sin.
•In Python, readability counts.
•Docstrings ("""blah blah""")
= How to use code
•Comments (#blah blah)
= Why (rationale) & how code works
9. Idiom
Potpourri
A selection of small, useful idioms.
Now we move on to the meat of the
tutorial: lots of idioms.
We'll start with some easy ones and
work our way up.
10. •In Python
•The comma is the tuple constructor syntax.
•A tuple is created on the right (tuple packing).
•A tuple is the target on the left (tuple unpacking).
•Further examples of unpacking:
a, b = b, a
>>> people = (['Guido', 'BDFL', 'unlisted'])
>>> for (name, title, phone) in people:
... print name, phone
...
Guido unlisted
temp = a
a = b
b = temp
Other
language
11. >>> import math
>>> math.pi / 3
1.0471975511965976
>>> angle = _
>>> math.cos(angle)
0.50000000000000011
>>> _
0.50000000000000011
•_ stores the last printed expression.
•When a result is None, _ doesn't change
•This only works in the interactive interpreter
12. •Don't do this
•This is very inefficient
•It has terrible memory usage and performance patterns
•The join() string method does all the copying in one pass
•If you want charicter between your substrings:
•If you need to apply a function to generate the substrings
colors = ['red', 'blue', 'green', 'yellow']
result = ''
for s in colors:
result += s
result = ''.join(colors)
result = ', '.join(colors)
result = ''.join(func(i) for i in items)
13. •Using for with dict
•in is generally faster
•This pattern also works for items in arbitrary containers
•such as lists, tuples, and sets
•in is also an operator
Good Bad
•d.keys() creates a static list of the dictionary keys
•Otherwise, you'll get an exception
•RuntimeError: dictionary changed size during iteration
for key in d:
print key
for key in d.keys():
print key
for key in d.keys():
d[str(key)] = d[key]
14. navs = {}
for (portfolio, equity, position) in data:
if portfolio not in navs: navs[portfolio] = 0
navs[portfolio] += position * prices[equity]
navs = {}
for (portfolio, equity, position) in data:
navs[portfolio] = (navs.get(portfolio, 0)
+ position * prices[equity])
•We often have to initialize dictionary entries before use:
•dict.get(key, default) removes the need for the test:
15. •Initializing mutable dictionary values:
•dict.setdefault(key, default) does the job efficiently:
•defaultdict
equities = {}
for (portfolio, equity) in data:
if portfolio in equities:
equities[portfolio].append(equity)
else:
equities[portfolio] = [equity]
equities = defaultdict(list)
for (portfolio, equity) in data:
equities[portfolio].append(equity)
equities = {}
for (portfolio, equity) in data:
equities.setdefault(portfolio, []).append(equity)
17. False True
False (== 0) True (== 1)
"" (empty string) any string but "" (" ", "anything")
0, 0.0 any number but 0 (1, 0.1, -1, 3.14)
[], (), {}, set() any non-empty container ([0], (None,), [''])
None almost any object that's not explicitly False
# do this: # not this:
if items: if len(items) != 0:
pass pass
# and definitely not this:
if items != []:
pass
•It's efficient to take advantage of the intrinsic truth values
19. In Other language In Python
a = 1
a = 2
b = a
Box "a" now contains an integer 1.
Now box "a" contains an integer 2.
"b" is a second box, with a
copy of integer 2.
Here, an integer 1 object has a tag labelle
Now the name "a" is attached to
an integer 2 object.
The name "b" is just a second tag
bound to the same object as "a".
20. •default value of a_list an empty list, is evaluated at function definition
•The correct way to get a default list (or dictionary, or set) is
to create it at run time instead, inside the function:
def bad_append(new_item, a_list=[]):
a_list.append(new_item)
return a_list
>>> print bad_append('one')
['one']
>>> print bad_append('two')
['one', 'two']
def good_append(new_item, a_list=None):
if a_list is None:
a_list = []
a_list.append(new_item)
return a_list
21. •Python's % operator works like C's printf function.
•By name with a dictionary
•By name using the local namespace:
name = 'David'
messages = 3
text = ('Hello %s, you have %i messages'
% (name, messages))
print text
print ('Hello %(name)s, you have %(messages)i '
'messages' % locals())
values = {'name': name, 'messages': messages}
print ('Hello %(name)s, you have %(messages)i '
'messages' % values)
22. •It's easy to sort a list in Python:
•We can use list's built-in sort method with a custom function:
•Sorting with keys
•You can use any existing one-argument function if applicable
def my_key(item):
return (item[1], item[3])
to_sort.sort(key=my_key)
a_list.sort()
def custom_cmp(item1, item2):
return cmp((item1[1], item1[3]),
(item2[1], item2[3]))
a_list.sort(custom_cmp)
23. •As a loop and As a list comprehension:
•As a generator expression:
•Use a list comprehension when a computed list is the desired end result.
•Use a generator expression when the computed list is just an intermediate step.
total = 0
for num in range(1, 101):
total += num * num
total = sum([num * num for num in range(1, 101)])
total = sum(num * num for num in range(1, 101))
month_codes = dict((fn(i+1), code)
for i, code in enumerate('FGHJKMNQUVXZ')
for fn in (int, str))
24. •The yield keyword turns a function into a generator.
•call a generator function, instead of running Python returns a generator object
•it has a next method. for loops just call the next method on the iterator
•A for loop can have an else clause, it is executed after the iterator runs dry
•but not after a break statement is executed.
def my_range_generator(stop):
value = 0
while value < stop:
yield value value += 1
for i in my_range_generator(10):
do_something(i)
for item in sequence:
if condition(item): break
else:
raise Exception('Condition not satisfied.')
25. •EAFP : Easier to ask forgiveness than permission
•LBYL: Look before you leap
•Generally EAFP is preferred, but not always.
•Duck typing
•If it walks like a duck, and talks like a duck, and looks like a duck: it's a duck
•Goose? Close enough.
•Exceptions
•Use coercion if an object must be a particular type.
•If x must be a string for your code to work, why not call
try:
return str(x)
except TypeError:
...
26. •To make a simultaneously importable module and executable script:
•Executed as a script though, the __name__ attribute is set to "__main__“
•Used to organize your project.
•Reduces entries in load-path.
•Reduces import name conflicts.
if __name__ == '__main__':
# script code here
package/
__init__.py
module1.py
subpackage/
__init__.py
module2.py
27. •Before writing any code
•Check Python's standard library.
•Check the Python Package Index (the "Cheese Shop"):
•http://cheeseshop.python.org/pypi
•Search the web. Google is your friend.
28. Python 2.7.6 (default, Jun 22 2015, 17:58:13)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> exit
Use exit() or Ctrl-D (i.e. EOF) to exit
>>> exit()
ubuntu@Ubuntu:~/$ sudo halt