前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >系统补白:流畅的python(1)

系统补白:流畅的python(1)

作者头像
一粒小麦
发布2019-07-18 16:49:20
7320
发布2019-07-18 16:49:20
举报
文章被收录于专栏:一Li小麦一Li小麦

流畅的python

对于发展迅速的组织来说,python可以极大地提高生产力。

比如:我可以5行代码爬取豆瓣电影排行前25的电影:

代码语言:javascript
复制
import json
from urllib.request import urlopen
url = 'http://api.douban.com/v2/movie/top250?start=25&count=25'
response = urlopen(url)
print(response.read().decode('utf-8'))

初学者学Python,不但入门容易,而且将来深入下去,可以编写那些非常非常复杂的程序。

那Python适合开发哪些类型的应用呢?

首选是网络应用,包括网站、后台服务等等;

其次是许多日常需要的小工具,包括系统管理员需要的脚本任务等等;

另外就是把其他语言开发的程序再包装起来,方便使用。

任何编程语言都有缺点,Python也不例外。优点说过了,那Python有哪些缺点呢?

第一个缺点就是运行速度慢,和C程序相比非常慢,因为Python是解释型语言,你的代码在执行时会一行一行地翻译成CPU能理解的机器码,这个翻译过程非常耗时,所以很慢。而C程序是运行前直接编译成CPU能执行的机器码,所以非常快。

但是大量的应用程序不需要这么快的运行速度,因为用户根本感觉不出来。

第二个缺点就是代码不能加密。如果要发布你的Python程序,实际上就是发布源代码,这一点跟C语言不同,C语言不用发布源代码,只需要把编译后的机器码(也就是你在Windows上常见的xxx.exe文件)发布出去。要从机器码反推出C代码是不可能的,所以,凡是编译型的语言,都没有这个问题,而解释型的语言,则必须把源码发布出去。

这个缺点仅限于你要编写的软件需要卖给别人挣钱的时候。好消息是目前的互联网时代,靠卖软件授权的商业模式越来越少了,靠网站和移动应用卖服务的模式越来越多了,后一种模式不需要把源码给别人。

再说了,现在如火如荼的开源运动和互联网自由开放的精神是一致的,互联网上有无数非常优秀的像Linux一样的开源代码,我们千万不要高估自己写的代码真的有非常大的“商业价值”。那些大公司的代码不愿意开放的更重要的原因是代码写得太烂了,一旦开源,就没人敢用他们的产品了。

瑕不掩瑜。python确实是简洁,可读性高。适用于大多数场景的语言。

代码语言:javascript
复制
import this

结果输出了一首诗:

总的来说,Python的哲学就是简单优雅,尽量写容易看明白的代码,尽量写少的代码。如果一个资深程序员向你炫耀他写的晦涩难懂、动不动就几万行的代码,你可以尽情地嘲笑他。

诗里这些哲学观点贯穿整个语言本身。

搭环境

去https://www.python.org/downloads/windows/

安装anaconda:anaconda是针对科学计算设计的多合一安装包,它已经内置了许多非常有用的第三方库,我们装上Anaconda,就相当于把数十个第三方模块自动安装好了,非常简单易用。

此外pip是python的第三方包管理工具。

数据类型

包括:

  • 布尔型(True/False)
  • 整型
  • 浮点型(小数或科学计数法)
  • 字符串
变量与命名

python是强类型语言。永远不可更改声明后的变量类型

计算式

//表示整数除法

**表示取幂

int可对浮点数或字符串数字进行四舍五入取整, float反之

字符串

'''可输出多行文本

str()方法可将其它类型转化为字符串

字符串可以通过 *进行复制

和列表类似可通过中括号提取。

代码语言:javascript
复制
# [:] 提取开头到结尾
# [start:]从起始点到结尾
# [:end] 从开头到end-1
# [start:end] 从开头提取到end-1
# [start:end:step] 从开头到end-1,每隔step提取一个
# 出现负数时,表示倒数第..个

把链表合并为字符串: ','.join(list)

案例:字符串分析与排版

以莎士比亚诗歌为例,分析以下字符串:

代码语言:javascript
复制
poem = '''You say that you love rain,
but you open your umbrella when it rains...
You say that you love the sun,
but you find a shadow spot when the sun shines...
You say that you love the wind,
But you close your windows when wind blows...
This is why I am afraid;
You say that you love me too...'''
print(poem[:13])
# You say that
print(len(poem))
# 字节长度289
print(poem.startswith('You'))
# True
print(poem.endswith('...'))
# True
print(poem.find('You'))
# 首次出现在0处
print(poem.rfind('You'))
# 最后出现在256处
print(poem.count('You'))
# 一共出现4次
代码语言:javascript
复制
print(poem.strip('...'))
# 去除收尾的神省略号

print(poem.title())
# 单词相关全部首字母大写
print(poem.upper())
# 转大写
print(poem.lower())
# 转小写
print(poem.swapcase())
# 大小写切换

print(poem.center(400))
print(poem.ljust(400))
print(poem.rjust(400))
# 把文本放到400个字节的空间里,居中,左对齐/右对齐

正是:

恋雨偏打伞,爱阳却遮凉。风来掩窗扉,叶公惊龙王。片言只语短,相思缱倦长。郎君说爱我,不敢细思量。

复杂数据

列表和元组

二者都是有序结构,前者以中括号包裹,可变,后者用小括号包裹,不可变。

  • 元组可以以 list()方法转化为列表
  • 列表的截取方法和字符串一致。
  • append(xxx):添加至尾部
  • extend(xxx):合并衔接两个列表
  • insert(index,xxx):插入
  • del list(index):删除指定位置
  • pop(index):获取同时从原列表删除
  • list.remove(xxx):删除列表中指定值
  • index(index):查询指定值位置
  • count(xxx):记录xxx出现的位置
  • 深度拷贝用 xxx.copy()
  • xxx in list :判断xxx是否在列表
  • sort()和sorted(list)都是字典排序,前者改变原数组内容,后者不会,并能返回一个新数组。
字典

创建字典可以直接赋值 {}。也可以通过 dict()转换。

代码语言:javascript
复制
lol=[['A','a'],['B','b']]
dict(lol)
{'B':'b','A','a'}
  • obj.update(obj2)可合并两个字典,重复键名时,以参数中的键值为准。
  • delete(key)可删除字典中指定的键值对
  • clear():清除所有
  • key in obj 判断是否存在此键
  • keys()返回所有键
  • values返回所有值
  • items():以列表套元组的形式返回所有键值对
  • copy也可以深度拷贝字典
集合

集合就像舍弃了值的字典,可以通过set方法创建,set一个列表,返回的可以是不重复的所有集合

in可以判断某个值是否存在于集合中

&取交集

-去差集

|取并集

^取亦或集(仅在两个集合中出现一次)

<=可判断前者是否为后者的真子集,后者称为前者的真超集

代码结构

一般补白

注释用的是 #

python代码结构严格依赖缩进。如果一行太长,可用 \断行。

选择结构: ifelifelse

假值:False,None,0,0.0,'',[].(),{},set()

除此之外全是真值。

编写文档:你在写一个方法时,通常要写帮助文档。python可以很友好地创建文档:

代码语言:javascript
复制
def echo(anything):
    'echo returns its input arguments'
    return anything
help(echo)

# Help on function echo in module __main__:

# echo(anything)
#     echo returns its input arguments
列表迭代

for循环比while循环更常用。

break打断循环。 continue跳到循环开始

循环外使用else:表示循环没有结束时做出的处置。

zip迭代:

代码语言:javascript
复制
e = ['a', 'b', 'c']
n = ['1', '2', '3', '4']
for _e, _n in zip(e, n):
    print _e+_n
# a1 b2 c3

range迭代:类似于切片(range(start,end,step )):

代码语言:javascript
复制
# 反向创建数列
for x in range(2,-1,-1):
    print(x)
# 2 1 0
list(range(2, -1, -1))
# [2,1,0]
推导
  • 列表推导一般格式:
代码语言:javascript
复制
number_list=list(表达式 for 循环变量 in 列表)
代码语言:javascript
复制
number_list=list(number for number in range(1,6))
# [1,2,3,4,5]
number_list=list(number-1 for number in range(1,6))
# [0,1,2,3,4]
number_list=list(number for number in range(1,6) if number%2=1)
# [1,3,5]
  • 多层嵌套的列表推导,比如打印一串4*3的数据:
代码语言:javascript
复制
rows = range(1, 4)
cols = range(1, 3)
# 迭代方法
for row in rows:
    for col in cols:
        print((row, col))

#推导方法
for cell in [(row,col) for row in rows for col in cols]:
    print(cell)
  • 字典推导
代码语言:javascript
复制
{key:值表达式 for key in 列表}

比如说我要统计一个字符串不同字母的出现次数:

代码语言:javascript
复制
letters = 'letters'
print({letter: letters.count(letter) for letter in letters})
# {'s': 1, 'r': 1, 'e': 2, 'l': 1, 't': 2}
  • 集合推导
代码语言:javascript
复制
print({number for number in range(1,6) if number%3==1})
# {[1,4]}
函数

一个函数如不显式调用 return 它将返回一个 None

位置参数的缺点在于,难以缺省,因此可以给定值,也可以设置缺省值。

  • 收集位置参数:
代码语言:javascript
复制
def func(*args):
    return args
# 返回一串位置参数组成的元组

def func2(**args):
    return args
# 返回的是{参数名:参数值}的字典
  • 生成器的自定义

对生成器进行迭代时,会记录上次访问的位置,不使用 return而使用 yield

比如说我要自定义一个生成器实现和range一样的功能:

代码语言:javascript
复制
def my_range(first=0,last=10,step=1):
    number=first
    while number<last
    yield number
    number+=step
  • 装饰器

有时候不想修改源代码,但想知道一个函数里究竟是什么,包含哪些参数。这是可以给它外包一层装饰器

我们定义一个装饰器:

代码语言:javascript
复制
def document_it(func):
    def new_function(*args, **kwargs):
        print('Running function:'+func.__name__)
        print('Positional arguments:',args)
        print('Keyword aguments:',kwargs)
        result = func(*args, **kwargs)
        print('result:',result)
    return new_function

def sum(a,b):
    return a+b

_sum=document_it(sum)
_sum(3,5)

# Running function: sum
# ('Positional arguments:', (3, 5))
# ('Keyword aguments:', {})
# ('result:', 8)

和文档一样,函数也有一个内置的属性 __name__

作用域与闭包

在一个函数中获取一个全局变量时很容易的。这在哪个语言中都是如此。

但在python中,一个函数尝试改变全局变量,则会失败。你需要这样写:

代码语言:javascript
复制
a=1
def fuc():
    global a
    print(a)
    a=2
    print(a)

fuc()

所谓“明了胜于隐晦”,你要取什么命名空间的变量,都有方法任意自取之

  • locals() 局部命名空间的字典
  • globals全局命名空间的字典
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-12-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 一Li小麦 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 流畅的python
  • 搭环境
  • 数据类型
    • 变量与命名
      • 计算式
        • 字符串
          • 案例:字符串分析与排版
          • 复杂数据
            • 列表和元组
              • 字典
                • 集合
                • 代码结构
                  • 一般补白
                    • 列表迭代
                      • 推导
                        • 函数
                          • 作用域与闭包
                          领券
                          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档