13、Pythonic

Pythonic:极具Python特色的Python代码(明显区别于其它语言的写法的代码)

用字典映射代替switch case语句

if/else可以代替switch但是非常不合适。

用字典代替switch:
day = 5
switcher = {
    0:'Sunday',
    1:'Monday',
    2:'Tuesday'
}

day_name = switcher.get(day,'Unknow')  #第一个参数为key,第二个参数为key不存在返回的值


用字典模拟带函数的switch:
day = 6
def get_sunday():
    return 'Sunday'

def get_monday():
    return 'Monday'

def get_tuesday():
    return 'Tuesday'

def get_default():
    return 'Unknow'

switcher = {
    0:get_sunday,
    1:get_monday,
    2:get_tuesday
}

day_name = switcher.get(day,get_default)()
print(day_name)

列表推导式

根据已经存在的列表创建新的列表:

a = [1,2,3,4,5,6,7,8]
b = [i * i for i in a]

print(b)
结果:[1, 4, 9, 16, 25, 36, 49, 64]

条件筛选:
a = [1,2,3,4,5,6,7,8]
b = [i**2 for i in a if i >= 5]

print(b)
结果:[25, 36, 49, 64]

a是集合、字典、元组也可以被推导。

字典编写列表推导式

students = {
    'tai':18,
    'park':32,
    'a':12
}

b = [key for key,value in students.items()]
print(b)
结果:['tai', 'park', 'a']
 
b = {value:key for key,value in students.items()}
print(b)
结果:{18: 'tai', 32: 'park', 12: 'a'}

迭代器(iterator)

可迭代对象(iterable):可被for in循环遍历的对象

普通对象变成迭代器需要实现__iter__()和__next__():
class BookCollection:
    def __init__(self):
        self.data = ['《往事》','《只能》','《回味》']
        self.cur = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.cur >= len(self.data):
            raise StopIteration()
        r = self.data[self.cur]
        self.cur += 1
        return r

books = BookCollection()
for book in books:
    print(book)

除了for in 遍历,还可以调用next方法:

books = BookCollection()
print(next(books))
print(next(books))
print(next(books))
迭代器具有一次性,只能遍历一次。若想再次遍历需要实例化一个新的对象。或者:
import copy
books = BookCollection()
books_copy = copy.copy(books)    #浅拷贝
若想实现深拷贝的话:
books_copy = copy.deepcopy(books)    #生成器

生成器(generator)

打印从0-10000的数字:
n = [i for i in range(0,10001)]
for i in n :
    print(i)

可以实现但是太消耗内存。n是一个列表,列表存储需要消耗内存的。


生成器:迭代器是针对一个对象的,生成器是针对一个函数的。
函数实现法:
def gen(max):
    n = 0
    while n <= max:
        print(n)
        n += 1

gen(100000)

每次打印的都是实时计算出来的结果,不是都存储起来再打印。
不应该在函数内部实现如print这样的操作。

生成器:
def gen(max):
    n = 0
    while n <= max:
        n += 1
        yield n

g = gen(10)
for i in g:
    print(i)
yield会接着返回的地方继续执行。

n = (i for i in range(0,10001))
此时n也为生成器。

None

  • None 空,不等于空字符串、空列表、0、False
  • None不仅在类型上不同,而且在值的比较上也不相同。
  • None永远对应False
a = None
print(not a)
print(a is None) 
结果:True
      True

a = []
print(not a)
print(a is None) 
结果:True
      False
 
推荐if a/if not a来判空。

对象存在并不一定是True

自定义的对象:
class Test():
    def __len__(self):
        return 0

test = Test()
if test:
    print('s')
else:
    print('f')
结果:f    #进的是False分支

test存在也有可能是False,需要考虑__len__与__bool__方法。

lenbool内置方法

如果对象没有定义__len__与__bool__方法则默认为True。

__len__代表长度,只能用int和bool返回。
使用len()时,则会调用对象的__len__,如果没有自定义__len__,求长度的时候会报错。

一旦加入了__bool__则由__bool__来控制对象的取值。

装饰器的副作用

import time

def decorator(func):
    def wrapper():
        print(time.time())
        func()
    return wrapper


def f1():
     print(f1.__name__)

f1()
结果:f1            #不加装饰器的函数名字

@decorator
def f1():
    print(f1.__name__)

f1()
结果:1532492964.0116718
      wrapper    #闭包函数的名字


python->help(len)->打印出内置说明
加了装饰器之后就无法找到函数的help()了

 
保证名字不改变:
import time

from functools import wraps
def decorator(func):
    @wraps(func)
    def wrapper():
        print(time.time())
        func()
    return wrapper

@decorator
def f1():
    print(f1.__name__)

f1()
结果:1532493245.2623913
     f1

wraps传入了原有函数,所以得知了原函数的信息,然后复制到闭包函数上,则信息得以保存。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容

  • 导言 产品是打磨出来的 用字典映射代替switch case 语句 字典内value可以传入函数!!!,但是需要注...
    tomtiddler阅读 184评论 0 0
  • 〇、前言 本文共108张图,流量党请慎重! 历时1个半月,我把自己学习Python基础知识的框架详细梳理了一遍。 ...
    Raxxie阅读 18,952评论 17 410
  • 个人笔记,方便自己查阅使用 Py.LangSpec.Contents Refs Built-in Closure ...
    freenik阅读 67,696评论 0 5
  • 一直都不否认自己是个懒惰的人,在生活的长河里随波逐流了很久。所幸老天眷顾给我一个幸福的家庭。 孩子出生后,我渐渐变...
    错落时空的好心情阅读 880评论 2 4
  • 啊~在此,我必须长长的叹一口气。终于来到了入门的总结关,仨字:脑仁疼! 之前,听伙伴...
    田丑儿阅读 231评论 0 1