logo资料库

Writing Idiomatic Python 3.pdf

第1页 / 共66页
第2页 / 共66页
第3页 / 共66页
第4页 / 共66页
第5页 / 共66页
第6页 / 共66页
第7页 / 共66页
第8页 / 共66页
资料共66页,剩余部分请下载后查看
Preface
Change List
Version 1.1, February 2, 2013
Version 1.2, February 17, 2013
Contents
Control Structures and Functions
If Statements
Avoid comparing directly to True, False, or None
Avoid repeating variable name in compound if statement
Avoid placing conditional branch code on the same line as the colon
For loops
Use the enumerate function in loops instead of creating an ``index'' variable
Use the in keyword to iterate over an iterable
Use else to execute code after a for loop concludes
Functions
Avoid using '', [], and {} as default parameters to functions
Use *args and **kwargs to accept arbitrary arguments
Working with Data
Lists
Use a list comprehension to create a transformed version of an existing list
Use the * operator to represent the ``rest'' of a list
Dictionaries
Use the default parameter of dict.get to provide default values
Use a dict comprehension to build a dict clearly and efficiently
Strings
Prefer the format function for formatting strings
Use ''.join when creating a single string for list elements
Chain string functions to make a simple series of transformations more clear
Classes
Use underscores in function and variable names to help mark ``private'' data
Define __str__ in a class to show a human-readable representation
Sets
Use sets to eliminate duplicate entries from Iterable containers
Use a set comprehension to generate sets concisely
Understand and use the mathematical set operations
Generators
Use a generator to lazily load infinite sequences
Prefer a generator expression to a list comprehension for simple iteration
Context Managers
Use a context manager to ensure resources are properly managed
Tuples
Use tuples to unpack data
Use _ as a placeholder for data in a tuple that should be ignored
Variables
Avoid using a temporary variable when performing a swap of two values
Organizing Your Code
Modules and Packages
Use modules for encapsulation where other languages would use Objects
Formatting
Use all capital letters when declaring global constant values
Avoid placing multiple statements on a single line
Format your code according to PEP8
Executable Scripts
Use sys.exit in your script to return proper error codes
Use the if __name__ == '__main__' pattern to allow a file to be both imported and run directly
Imports
Prefer absolute imports to relative imports
Do not use from foo import * to import the contents of a module.
Arrange your import statements in a standard order
General Advice
Avoid Reinventing the Wheel
Learn the Contents of the Python Standard Library
Get to know PyPI (the Python Package Index)
Modules of Note
Learn the contents of the itertools module
Use functions in the os.path module when working with directory paths
Contributors
Writing Idiomatic Python Jeff Knupp 2013 i
ii Copyright 2013 by Jeff Knupp All rights reserved. No part of this book may be reproduced in any form or by any electronic or mechanical means without permission in writing from the author. Jeff Knupp Visit me at www.jeffknupp.com
Preface There’s a famous old quote about writing maintainable software: Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. --John Woods comp.lang.c++ While I’m not usually one for aphorisms, this one strikes a chord with me. Maybe it’s because I’ve spent my professional career writing software at huge companies, but I have yet to inherit code that didn’t eventually cause me to curse the original author at some point. Everyone (besides you, of course, dear reader) struggles to write code that’s easy to maintain. When Python became popular, many thought that, because of its terseness, it would naturally lead to more maintainable software. Alas, maintainability is not an emergent property of using an expressive lan- guage. Badly written Python code is just as unmaintainable as badly written C++, Perl, Java and all the rest of the languages known for their, ahem, read- ability. Terse code is not a free lunch. So what do we do? Resign ourselves to maintaining code we can’t understand? Rant on Twitter and The Daily WTF about the awful code we have to work on? What must we do to stop the pain? Write. Idiomatic. Code. It’s that simple. Idioms in a programming language are a sort of lingua franca to let future readers know exactly what we’re trying to accomplish. We may document our code extensively, write exhaustive unit tests, and hold code reviews three times a day, but the fact remains: when someone else needs to make changes, the code is king. If that someone is you, all the documentation in the world won’t help you understand unreadable code. After all, how can you even be sure the code is doing what the documentation says? We’re usually reading someone else’s code because there’s a problem. But idiomatic code helps here, too. Even if it’s wrong, when code is written idiomat- iii
iv PREFACE ically, it’s far easier spot bugs. Idiomatic code reduces the cognitive load on the reader. After learning a language’s idioms, you’ll spend less time wondering “Wait, why are they using a named tuple there” and more time understanding what the code actually does. After you learn and internalize a language’s idioms, reading the code of a like- minded developer feels like speed reading. You’re no longer stopping at every line, trying to figure out what it does while struggling to keep in mind what came before. Instead, you’ll find yourself almost skimming the code, thinking things like ‘OK, open a file, transform the contents to a sorted list, generate the giant report in a thread-safe way.’ When you have that level of insight into code someone else wrote, there’s no bug you can’t fix and no enhancement you can’t make. All of this sounds great, right? There’s only one catch: you have to know and use a language’s idioms to benefit. Enter Writing Idiomatic Python. What started as a hasty blog post of idioms (fueled largely by my frustration while fixing the code of experienced developers new to Python) is now a full-fledged eBook. I hope you find the book useful. It is meant to be a living document, updated If you find an in near-real time with corrections, clarifications, and additions. error in the text or have difficulty deciphering a passage, please feel free to email me at jeff@jeffknupp.com. With their permission, I’ll be adding the names of all who contribute bug fixes and clarifications to the appendix. Cheers, Jeff Knupp January, 2013
Change List Version 1.1, February 2, 2013 • New idiom: “Use sys.exit in your script to return proper error codes” idiom • Greatly expanded discussion in “Avoid comparing directly to True, False, or None” and added mention of comparison to None when checking if optional arguments were set (to match the idiom “Avoid using ”, [], and {} as default parameters to functions”. • Expanded “Use the * operator to represent the”rest” of a list” idiom ex- • Fixed page numbering issue causing numbers in table of contents and index panded with additional cases not to match the text • Fixed various typos and grammatical errors • Changed font size and various layout issues (some of which caused text to run off the page • Changed preface text Version 1.2, February 17, 2013 • Improved formatting for epub and Kindle versions • Fixed various typos and grammatical errors v
vi CONTENTS Contents Preface Change List Version 1.1, February 2, 2013 . . . . . . . . . . . . . . . . . . . . . . . . Version 1.2, February 17, 2013 . . . . . . . . . . . . . . . . . . . . . . . Contents 1 Control Structures and Functions 1.1 1.2 For loops If Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1.1 Avoid comparing directly to True, False, or None . . . . . 1.1.2 Avoid repeating variable name in compound if statement . 1.1.3 Avoid placing conditional branch code on the same line as the colon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2.1 Use the enumerate function in loops instead of creating an . . . . . . . . . . . . . . . . . . . . . . . . 1.2.2 Use the in keyword to iterate over an iterable . . . . . . 1.2.3 Use else to execute code after a for loop concludes . . . . 1.3 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.1 Avoid using '', [], and {} as default parameters to func- tions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.2 Use *args and **kwargs to accept arbitrary arguments . . “index” variable 2 Working with Data 2.1 Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1.1 Use a list comprehension to create a transformed version of an existing list . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1.2 Use the * operator to represent the “rest” of a list iii v v v vi 1 1 1 4 5 6 6 7 8 9 9 11 15 15 15 16
CONTENTS vii 17 17 2.5 Sets “private” data 2.2 Dictionaries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2.1 Use the default parameter of dict.get to provide default values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2.2 Use a dict comprehension to build a dict clearly and 18 efficiently . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 2.3 Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3.1 Prefer the format function for formatting strings . . . . . . 19 2.3.2 Use ''.join when creating a single string for list elements 20 2.3.3 Chain string functions to make a simple series of transfor- mations more clear . . . . . . . . . . . . . . . . . . . . . . . 2.4 Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.4.1 Use underscores in function and variable names to help mark . . . . . . . . . . . . . . . . . . . . . . . . . 2.4.2 Define __str__ in a class to show a human-readable repre- sentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.5.1 Use sets to eliminate duplicate entries from Iterable con- tainers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.5.2 Use a set comprehension to generate sets concisely . . . . 2.5.3 Understand and use the mathematical set operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.6.1 Use a generator to lazily load infinite sequences . . . . . . 2.6.2 Prefer a generator expression to a list comprehension for simple iteration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.7.1 Use a context manager to ensure resources are properly managed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.8 Tuples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.8.1 Use tuples to unpack data . . . . . . . . . . . . . . . . . . 2.8.2 Use _ as a placeholder for data in a tuple that should be ignored . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.9.1 Avoid using a temporary variable when performing a swap . . . . . . . . . . . . . . . . . . . . . . . . . . 2.7 Context Managers 2.6 Generators 2.9 Variables of two values 33 34 34 35 35 36 37 37 21 22 22 25 26 26 28 29 31 31 3 Organizing Your Code 3.1 Modules and Packages . . . . . . . . . . . . . . . . . . . . . . . . . 3.1.1 Use modules for encapsulation where other languages would use Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 39 39
viii CONTENTS 3.2 Formatting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2.1 Use all capital letters when declaring global constant values 3.2.2 Avoid placing multiple statements on a single line . . . . . . 3.2.3 Format your code according to PEP8 . . . . . . . . . . . . . 3.3 Executable Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3.1 Use sys.exit in your script to return proper error codes 3.3.2 Use the if __name__ == '__main__' pattern to allow a file to be both imported and run directly . . . . . . . . . . Imports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.4.1 Prefer absolute imports to relative imports . . . . . . 3.4.2 Do not use from foo import * to import the contents of a . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.4.3 Arrange your import statements in a standard order . . . . module. 3.4 4 General Advice 4.1 Avoid Reinventing the Wheel . . . . . . . . . . . . . . . . . . . . . 4.1.1 Learn the Contents of the Python Standard Library . . . . 4.1.2 Get to know PyPI (the Python Package Index) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2.1 Learn the contents of the itertools module . . . . . . . . . . 4.2.2 Use functions in the os.path module when working with directory paths . . . . . . . . . . . . . . . . . . . . . . . . . 4.2 Modules of Note 5 Contributors 41 41 42 43 44 44 46 47 47 48 49 51 51 51 52 53 53 54 55
分享到:
收藏