原文:https://learnxinyminutes.com/docs/python3/
单行注释用#开头.
"""
多行文字可以用3个"包裹,
这也经常用于多行注释
"""
####################################################
## 1.数据类型和操作
####################################################
# 定义一个数字类型
3 # => 3
# 基本的数学运算
1 + 1 # => 2
8 - 1 # => 7
10 * 2 # => 20
35 / 5 # => 7.0
# 正数或负数的相除,结果截断为整数
5 // 3 # => 1
5.0 // 3.0 # => 1.0 # 也适用于小数
-5 // 3 # => -2
-5.0 // 3.0 # => -2.0
# 2数相除结果一定为浮点数
10.0 / 3 # => 3.3333333333333335
# 求余运算
7 % 3 # => 1
# 2的3次方
2**3 # => 8
# 用()做优先运算
(1 + 3) * 2 # => 8
# Boolean 类型 (开头大写)
True
False
# 用 not 表示非运算
not True # => False
not False # => True
# 或运算和与运算
True and False # => False
False or True # => True
#用整数代表boolean运算
# False 是 0 True 是 1
# Don't mix up with bool(ints) and bitwise and/or (&,|)
0 and 2 # => 0
-5 or 0 # => -5
0 == False # => True
2 == True # => False
1 == True # => True
-5 != False != True #=> True
# 等于 ==
1 == 1 # => True
2 == 1 # => False
# 不等于 !=
1 != 1 # => False
2 != 1 # => True
# 其他的比较
1 < 10 # => True
1 > 10 # => False
2 <= 2 # => True
2 >= 2 # => True
# 可以连接起比较
1 < 2 < 3 # => True
2 < 3 < 2 # => False
# (is vs. ==) is 对比的是2个变量是否指向统一对象, 但是 == 对比的
# 是2个对象是否有相同的值
a = [1, 2, 3, 4] # 指向一个list, [1, 2, 3, 4]
b = a # b也指向a所指向的list
b is a # => True, a,b都指向同一对象
b == a # => True, a,b的值自然也相等
b = [1, 2, 3, 4] # 指向一个新的 list, [1, 2, 3, 4]
b is a # => False, a,b指向的不是同一个对象
b == a # => True, a,b所指向的对象的值相同
# 字符串可以用""或者''
"This is a string."
'This is also a string.'
# 字符串也能进行拼接! 连续相加效率很低,每次使用+
# 会重新申请内存生成新的字符串
"Hello " + "world!" # => "Hello world!"
# 也可以直接拼接
"Hello " "world!" # => "Hello world!"
# 用[index]可以访问任意字符
"This is a string"[0] # => 'T'
# 字符串的长度
len("This is a string") # => 16
# .format 用来格式化字符串
"{} can be {}".format("Strings", "interpolated")
# => "Strings can be interpolated"
# 也可以使用'{0}','{1}'形式的占位符
"{0} be nimble, {0} be quick, {0} jump over the {1}".format("Jack", "candle stick")
# => "Jack be nimble, Jack be quick, Jack jump over the candle stick"
# 使用'{name}'形式的占位符
"{name} wants to eat {food}".format(name="Bob", food="lasagna")
# => "Bob wants to eat lasagna"
# 如果需要让你的 Python 3 代码运行在 Python 2.5或者以下,你需要使用老版本
# 的格式方法
"%s can be %s the %s way" % ("Strings", "interpolated", "old")
# => "Strings can be interpolated the old way"
# None 是个对象
None # => None
# 不要用'=='判断对象是否为None.
"etc" is None # => False
None is None # => True
# None, 0, 和空的strings/lists/dicts/tuples 都是 False.
# 其他所有都是 True
bool(None) # => False
bool(0) # => False
bool("") # => False
bool([]) # => False
bool({}) # => False
bool(()) # => False
####################################################
## 2. 变量和集合
####################################################
# Python的打印方法
print("I'm Python. Nice to meet you!") # => I'm Python. Nice to meet you!
# 用可选的参数 end 来改变打印的末尾.
print("Hello, World", end="!") # => Hello, World!
# 获取用户输入数据
input_string_var = input("Enter some data: ") #得到输入的数据(字符串)
# 注意:Python先前的版本, input() 方法也命名为 raw_input()
# 再分配值前,不需要声明变量
# 用小写字母下划线分隔表示变量 lower_case_with_underscores
some_var = 5
some_var # => 5
# 访问未分配值的变量会报错.
some_unknown_var # Raises a NameError
# if else 语句
"yahoo!" if 3 > 2 else 2 # => "yahoo!"
input_str=input('enter you data:');
if input_str=='0':
print('is 0')
elif input_str=='1':
print('is 1')
else:
print(input_str)
# Lists 存储队列
li = []
# 你可以这样声明一个预先有值的Lists
other_li = [4, 5, 6]
# 往list的末尾追加元素
li.append(1) # [1]
li.append(2) # [1, 2]
li.append(4) # [1, 2, 4]
li.append(3) # [1, 2, 4, 3]
# 移除队列最后一个元素
li.pop() # => 3
#先放回来
li.append(3) #[1, 2, 4, 3]
# 访问任意位置上的元素
li[0] # => 1
# 访问最后一个元素
li[-1] # => 3
# 下标越界异常
li[4] # Raises an IndexError
# 截取访问list的某个片段
# 左闭右开的模式
li[1:3] # => [2, 4]
# 从下标为2一直到Lists 最后一个元素
li[2:] # => [4, 3]
# 从最开始到下标为2
li[:3] # => [1, 2, 4]
# 下标0,2,4..跳跃2
li[::2] # =>[1, 4]
# 返回一份反转的Lists
li[::-1] # => [3, 4, 2, 1]
# 用以上3种方法可以访问list的任意片段
# li[start:end:step]
# 用截取复制一个list
li2 = li[:] # => li2 = [1, 2, 4, 3] 但是 (li2 is li) 返回False,是不同的对象.
# 用del方法移除li下标为2的元素
del li[2] # [1, 2, 3]
# 在指定元素第一次出现的位置移除它
li.remove(2) # [1, 3]
li.remove(2) # 移除一个不存在的元素会出异常 Raises a ValueError
# 在指定的位置插入元素
li.insert(1, 2) # li is now [1, 2, 3] again
# 找到指定元素第一次出现的位置
li.index(2) # => 1
li.index(4) # 没有该元素会出异常 Raises a ValueError
# 拼接2个list
# 注意:li和other_li并未改变
li + other_li # => [1, 2, 3, 4, 5, 6]
# 连接Lists 用 "extend()" 连接的Lists 会改变
li.extend(other_li) # 现在 li 是 [1, 2, 3, 4, 5, 6]
# 检查list是否含有指定元素
1 in li # => True
# list的长度
len(li) # => 6
# Tuples 很像 list但是是不可变的
tup = (1, 2, 3)
tup[0] # => 1
tup[0] = 3 # Raises a TypeError
#注意长度为1的tuple必须在最后一个元素的后面有个','逗号
#其他长度的不需要
type((1)) # => <class 'int'>
type((1,)) # => <class 'tuple'>
type(()) # => <class 'tuple'>
# list上的大部分方法tuple上也有
len(tup) # => 3
tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
tup[:2] # => (1, 2)
2 in tup # => True
# 你可以用tuples (或者lists) 为变量赋值
a, b, c = (1, 2, 3) # a 值为 1, b 值为 2 , c 值为 3
# 也可以这样赋值(不能存在2个*号)
a, *b, c = (1, 2, 3, 4) # a is now 1, b is now [2, 3] and c is now 4
# 也可以不用括号自动创建tuple
d, e, f = 4, 5, 6
# 如何轻松的交换2个变量的值
e, d = d, e # d 现在是 5, e 现在是 4
# Dictionaries词典map
empty_dict = {}
# 预充式方式新建dict
filled_dict = {"one": 1, "two": 2, "three": 3}
# 主页dictionaries 的keys 必须是不可变类型. 这是为了保证
#key能够转化为常数的hash值用来快速查找
# 不可变类型包括: ints, floats, strings, tuples.
invalid_dict = {[1,2,3]: "123"} # => Raises a TypeError: unhashable type: 'list'
valid_dict = {(1,2,3):[1,2,3]} # 值可以是任意类型
# 用key来查找值
filled_dict["one"] # => 1
#用‘keys()’来迭代所有的key,我们需要用'list()'方法转化为list,
#稍后会解释这个。注意:字典的key是无序的,你的结果可能顺序和我的不同
list(filled_dict.keys()) # => ["three", "two", "one"]
#用'values()'来迭代所有的值,我们也需要用'list()'方法转化为list,
# 顺序也是无序的
list(filled_dict.values()) # => [3, 2, 1]
# 用'in'来检查词典是否包含此key
"one" in filled_dict # => True
1 in filled_dict # => False
# 查找是用不存在的key会出 KeyError
filled_dict["four"] # KeyError
# 用"get()" 方法来避免出现 KeyError
filled_dict.get("one") # => 1
filled_dict.get("four") # => None
# get方法能设置默认值当该值不存在
filled_dict.get("one", 4) # => 1
filled_dict.get("four", 4) # => 4
# 往词典插入值'setdefault()'只有在给定的key不存在时才生效
filled_dict.setdefault("five", 5) # filled_dict["five"] is set to 5
filled_dict.setdefault("five", 6) # filled_dict["five"] is still 5
# 往字典里插入值
filled_dict.update({"four":4}) # => {"one": 1, "two": 2, "three": 3, "four": 4}
#filled_dict["four"] = 4 #另一个方法往字典插入值,如果key存在会覆盖原值
# 用del来从词典删除元素
del filled_dict["one"]
# 从3.5开始也可以这样为dict赋值
{'a': 1, **{'b': 2,'c':3}} # => {'a': 1, 'b': 2,'c':3}
{'a': 1, **{'a': 2}} # => {'a': 2}
# Sets store
empty_set = set()
# 用一些值初始化set. 不能有重复的元素
some_set = {1, 1, 2, 2, 3, 4} # some_set 现在是 {1, 2, 3, 4}
# 和词典一样, set的元素也必须啊是不可变类型
invalid_set = {[1], 1} # => Raises a TypeError: unhashable type: 'list'
invalid_set = [1, [1]} # => Raises a TypeError: unhashable type: 'list'
valid_set = {(1,), 1}
# 把set赋值给新的变量
filled_set = some_set
# 为set添加更多的元素
filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5}
# 用 &查找出2个set重合的部分
other_set = {3, 4, 5, 6}
filled_set & other_set # => {3, 4, 5}
# 结合2个set用|
filled_set | other_set # => {1, 2, 3, 4, 5, 6}
# 找出2个se,t前者和后者不同部分用 -
{1, 2, 3, 4} - {2, 3, 5} # => {1, 4}
# 用^找出2个set不同的部分
{1, 2, 3, 4} ^ {2, 3, 5} # => {1, 4, 5}
# 判断左边的set是否是右边的父集
{1, 2} >= {1, 2, 3} # => False
# 判断左边的set是否是右边的子集
{1, 2} <= {1, 2, 3} # => True
# 判断set是否包含此元素
2 in filled_set # => True
10 in filled_set # => False
####################################################
## 3. Control Flow and Iterables
####################################################
# 新建一个变量
some_var = 5
# if语句. 缩进在python中很重要!
# prints "some_var is smaller than 10"
if some_var > 10:
print("some_var is totally bigger than 10.")
elif some_var < 10: # This elif clause is optional.
print("some_var is smaller than 10.")
else: # This is optional too.
print("some_var is indeed 10.")
"""
循环遍历list
prints:
dog is a mammal
cat is a mammal
mouse is a mammal
"""
for animal in ["dog", "cat", "mouse"]:
print("{} is a mammal".format(animal))
"""
"range(number)" 返回一系列连续增加的整数
从0到给定的数减1(不包含该数)
prints:
0
1
2
3
"""
for i in range(4):
print(i)
"""
"range(lower, upper)" 返回一系列连续增加的整数
从较低的数开始到较高的数减1(不包含该数)
prints:
4
5
6
7
"""
for i in range(4, 8):
print(i)
"""
"range(lower, upper, step)" 返回一系列连续增加的整数
从较低的数开始到较高的数减1(不包含该数)跳跃的间距为step默认为1
prints:
4
6
"""
for i in range(4, 8, 2):
print(i)
"""
循环直到条件不满足
prints:
0
1
2
3
"""
x = 0
while x < 4:
print(x)
x += 1 # x = x + 1的简写
# 用 try/except 处理异常
try:
# 用 "raise" 抛出异常
raise IndexError("This is an index error")
except IndexError as e:
pass # Pass不是最好的解决办法,通常需要在这进行处理
except (TypeError, NameError):
pass # 如果需要多个异常也能一起处理
else: #可选的子句,必须在所有try/except后面
print("All good!") # 在try语句中不会
finally: # 所有情况执行后
print("We can clean up resources here")
# 确保不管使用过程中是否发生异常都会执行必要的“清理”操作,
# 释放资源,比如文件使用后自动关闭、线程中锁的自动获取和释放
# 用于代替try/except
with open("myfile.txt") as f:
for line in f:
print(line)
# Python 提供一个抽象的基类称为 Iterable.
# iterable 是一个可以看为队列的可迭代对象
#iterable是实现了iter()方法的对象.更确切的说,
#是container.iter()方法,该方法返回的是的一个iterator对象
#因此iterable是你可以从其获得iterator的对象.使用iterable时,
#将一次性返回所有结果,都存放在内存中,并且这些值都能重复使用.
filled_dict = {"one": 1, "two": 2, "three": 3}
our_iterable = filled_dict.keys()
print(our_iterable)
# => dict_keys(['one', 'two', 'three']).这个对象实现了Iterable 接口
# 我们可以用for in迭代它.
for i in our_iterable:
print(i) # 输出 one, two, three
# 但是我们不能用下标访问其中的元素.
our_iterable[1] # Raises a TypeError
# iterable是实现了__iter__()方法的对象.更确切的说,是container.__iter__()方法,
# 该方法返回的是的一个iterator对象,因此iterable是你可以从其获得iterator的对象.
our_iterator = iter(our_iterable)
# 调用next()方法时,实际上产生了2个操作:
# 更新iterator状态,令其指向后一项,以便下一次调用
# 返回当前结果
# iterator是消耗型的,即每一个值被使用过后,就消失了.
next(our_iterator) # => "one"
next(our_iterator) # => "two"
next(our_iterator) # => "three"
# 当iterator返回所有的值后会抛出 StopIteration Exception
next(our_iterator) # Raises StopIteration
# 你可以用'list()'获取到iterator的所有元素
list(filled_dict.keys()) # => Returns ["one", "two", "three"]
####################################################
## 4. 方法
####################################################
# 用"def" 来新建一个方法
def add(x, y):
print("x is {} and y is {}".format(x, y))
return x + y #返回值
# 传参调用方法
add(5, 6) # => 打印出 "x is 5 and y is 6" 返回11
# 用关键词参数调用方法
add(y=6, x=5)
# 你可以定义一个接收多参数的函数
def varargs(*args):
return args
varargs(1, 2, 3) # => (1, 2, 3)
# 你可以定义一个接收多关键词参数的函数
def keyword_args(**kwargs):
return kwargs
# 生成了一个词典
keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"}
# 也可以和在一起
def all_the_args(*args, **kwargs):
print(args)
print(kwargs)
"""
all_the_args(1, 2, a=3, b=4) prints:
(1, 2)
{"a": 3, "b": 4}
"""
# 我们也能这样调
# 用 * 展开 tuples 用 ** to 展开 kwargs.
args = (1, 2, 3, 4)
kwargs = {"a": 3, "b": 4}
all_the_args(*args) # 等于调用 all_the_args(1, 2, 3, 4)
all_the_args(**kwargs) # 等于调用all_the_args(a=3, b=4)
all_the_args(*args, **kwargs) # 等于调用all_the_args(1, 2, 3, 4, a=3, b=4)
# 多返回值
def swap(x, y):
return y, x # 返回一个没有括号的tuple
x = 1
y = 2
x, y = swap(x, y) # => x = 2, y = 1
# (x, y) = swap(x,y) # 括号可有可无.
# 变量范围
x = 5 #全局变量
def set_x(num):
# 本地变量和全局变量不同它的作用范围就在方法体内
x = num # => 43
print (x) # => 43
def set_global_x(num):
global x
print (x) # => 5
x = num # global x 设置为6
print (x) # => 6
set_x(43)
set_global_x(6)
# python拥有一流的方法
def create_adder(x):
def adder(y):
return x + y
return adder
add_10 = create_adder(10)
add_10(3) # => 13
# 匿名方法
(lambda x: x > 2)(3) # => True
(lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5
# 内建高阶函数
list(map(add_10, [1, 2, 3])) # => [11, 12, 13]
list(map(max, [1, 2, 3], [4, 2, 1])) # => [4, 2, 3]
list(filter(lambda x: x > 5, [3, 4, 5, 6, 7])) # => [6, 7]
# list comprehensions 能更好的 maps 和 filters
# List comprehension 能把结果存储为list
[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7]
# set and dict comprehensions
{x for x in 'abcddeef' if x not in 'abc'} # => {'d', 'e', 'f'}
{x: x**2 for x in range(5)} # => {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
####################################################
## 5. Modules
####################################################
# 导入 modules
import math
print(math.sqrt(16)) # => 4.0
# 可以从 modules导入具体的方法
from math import ceil, floor
print(ceil(3.7)) # => 4.0
print(floor(3.7)) # => 3.0
# 也可以导入modules中导入所有的方法.
# 不推荐这样做
from math import *
# 也能自定义module名字
import math as m
math.sqrt(16) == m.sqrt(16) # => True
# Python modules 就是普通的 python 文件. 你也可以自己写,
# 导入自己写的,modules的名字就是文件的名字
# 你能访问出所有module中的属性和方法
import math
dir(math)
# 如果有一个Python脚本也叫 math.py 和你当前的脚本在同一文件夹,
# 会加载这个脚本而不是python内置的,因为他的优先级是比内置的高
####################################################
## 6. Classes
####################################################
# 用 "class" 来定义一个 class
class Human:
# 类的属性,被这个类所有实例所分享
species = "H. sapiens"
# 初始化方法,当这个类被实例化后调用.
# 前后的双下划线定义的对象或属性是Python内部的名字
# 用来区别其他用户自定义的命名,以防冲突。
def __init__(self, name):
# 为实例分配属性并赋值
self.name = name
self._age = 0
# 所有方法都已self作为第一个参数
def say(self, msg):
print ("{name}: {message}".format(name=self.name, message=msg))
def sing(self):
return 'yo... yo... microphone check... one two... one two...'
# classmethod 可以直接类名.方法名()来调用
# 持有cls参数,可以来调用类的属性,类的方法,实例化对象等
@classmethod
def get_species(cls):
return cls.species
# static method 可以直接类名.方法名()来调用
@staticmethod
def grunt():
return "*grunt*"
# 在python中,我们需要对外暴露一个成员变量的时候,
# 我们往往需要对外部输入的值进行判断,以确保是符合我们的期望的。
# age变成私有的成员变量。然后写一个getter用于供外部取得age值;一个
# setter函数用于供外部设置age值,并对age值进行一定的判断。例如:
def age_getter(self):
return self._age
def age_setter(self, age):
if isinstance(age, str) and age.isdigit():
age = int(age)
else:
raise ValueError("age is illegal")
if isinstance(age,int):
self._age = age
# 那么我就需要student.age_getter()取得age,student.age_setter()
# 设置age值。但是这样实现了功能,但是的确使得调用变得比较麻烦
# property 把一个方法变成属性调用的
class Student(object):
def __init__(self):
self._age = None
@property
def age(self):
return self._age
@age.setter
def age(self, age):
if isinstance(age, int):
self._age = age
return
if isinstance(age, str) and age.isdigit():
age = int(age)
self._age = age
else:
raise ValueError("age is illegal")
@age.deleter
def age(self):
del self._age
student = Student()
student.age = 20
print student.age
del student.age
# i.age # => raise an AttributeError
# 上面的例子中用@property、x.setter x.deleter实现了
# 属性的读取、赋值、和删除
# 在cmd 中直接运行.py文件,则__name__的值是'__main__';
# 而在import 一个.py文件后,__name__的值就不是'__main__'了;
# 从而用if __name__ == '__main__'来判断是否是在直接运行该.py文件
if __name__ == '__main__':
# 实例化一个类
i = Human(name="Ian")
i.say("hi") # "Ian: hi"
j = Human("Joel")
j.say("hello") # "Joel: hello"
#i和j都是Human的实例
i.say(i.get_species()) # "Ian: H. sapiens"
# 改变共享属性
Human.species = "H. neanderthalensis"
i.say(i.get_species()) # => "Ian: H. neanderthalensis"
j.say(j.get_species()) # => "Joel: H. neanderthalensis"
# 调用静态方法
print(Human.grunt()) # => "*grunt*"
# 不能用实例调用静态方法
# 因为 i.grunt() will automatically 会用自动用self作为第一个参数
print(i.grunt())
# => TypeError: grunt() takes 0 positional arguments
but 1 was given
####################################################
## 6.1 多重继承
####################################################
# 声明另一个类
class Bat:
species = 'Baty'
def __init__(self, can_fly=True):
self.fly = can_fly
# 这个类也有say这个方法
def say(self, msg):
msg = '... ... ...'
return msg
# 也有自己的方法
def sonar(self):
return '))) ... ((('
if __name__ == '__main__':
b = Bat()
print(b.say('hello'))
print(b.fly)
# 为了模块化开发可以把上面的类放在不同的文件中
# human.py ,bat.py
# 用以下格式导入其他文件
# to import functions from other files use the following format
# from "filename-without-extension" import "function-or-class"
# superhero.py
from human import Human
from bat import Bat
# Batman 继承自 Human 和 Bat
class Batman(Human, Bat):
# Batman 有自己的属性
species = 'Superhero'
def __init__(self, *args, **kwargs):
# 用 *args 和 **kwargs 能更好的传递参数
Human.__init__(self, 'anonymous', *args, **kwargs)
Bat.__init__(self, *args, can_fly=False, **kwargs)
# 重写name 的值
self.name = 'Sad Affleck'
def sing(self):
return 'nan nan nan nan nan batman!'
if __name__ == '__main__':
sup = Batman()
# 实例类型判断、
if isinstance(sup, Human):
print('I am human')
if isinstance(sup, Bat):
print('I am bat')
if type(sup) is Batman:
print('I am Batman')
print(Batman.__mro__) # => (<class '__main__.Batman'>, <class
'human.Human'>, <class 'bat.Bat'>, <class 'object'>)
print(sup.get_species()) # => Superhero
print(sup.sing()) # => nan nan nan nan nan batman!
# 调用Human的方法
sup.say('I agree') # => Sad Affleck: I agree
# 调用Bat的方法
print(sup.sonar()) # => ))) ... (((
sup.age = 100
print(sup.age)
print('Can I fly? ' + str(sup.fly))