首先, 什么是 Python? 用 python 作者 Guido van Rossum 自己的话来说, Python 是这样的一门语言:
"它是一门高级编程语言, 它的核心设计理念是让所有代码变得更易阅读, 并给开发者们提供一种" 仅仅几行代码就能编写编程逻辑 " 的语法.
那么, 对我来说, 让我学习 Python 的第一个理由, 就是它漂亮而优雅, 能够顺畅自然地实现我的想法.
另一个理由, 就是 Python 支持多种编程领域, 如:
数据科学
Web 开发
机器学习
比如, Quora,Pinterest,Spotify, 这些项目, 都是使用 python 开发他们的后端.
那么, 接下来, 就开始学习 Python 吧!
基础
1. 变量
可以把变量简单理解为一个存储值的单词.
讲道理, 变量是什么就不用特地解释了... 大家都懂.
在 Python 里面, 定义变量, 给变量赋值都非常简单. 比如你想把数字 1 存储到一个变量里面, 而这个变量名叫 one, 那么, 你只需要这样:
one = 1
非常简单吧? 举一反三, 完全可以自由发挥, 就像下面, 把 2 赋值给 two, 把 10000 赋值给 some_number:
- two = 2
- some_number = 10000
当然, 除了整型以外, 我们也可以设置布尔类型, 字符串, 单精度, 以及一些其他数据类型. 如下:
- # booleans
- true_boolean = True
- false_boolean = False
- # string
- my_name = "Leandro Tk"
- # float
- book_price = 15.80
2. 流程控制: 分支语句
if, 这个语句用来判断是否符合条件, 它的后面紧跟着逻辑表达式, 表达式最后的值为 True 或 False, 如果是 true, 则执行 if 里面的语句. 如下:
- if True:
- print("Hello Python If")
- if 2> 1:
- print("2 is greater than 1")
因为 2 大于 1, 条件成立, 所以 print 语句就会被执行
当然, 如果不满足条件, 那么 else 就派上用场了!
如果, if 后面跟着的逻辑表达式最终值是 false, 则会运行 else 里面的程序, 如下:
- if True:
- print("Hello Python If")
- if 2> 1:
- print("2 is greater than 1")
因为 2 大于 1, 条件成立, 所以 print 语句就会被执行
当然, 如果不满足条件, 那么 else 就派上用场了!
如果, if 后面跟着的逻辑表达式最终值是 false, 则会运行 else 里面的程序, 如下:
- if 1> 2:
- print("1 is greater than 2")
- else:
- print("1 is not greater than 2")
你也可以使用 elif, 是 else if 的缩写, 但千万别写错~
- if 1> 2:
- print("1 is greater than 2")
- elif 2> 1:
- print("1 is not greater than 2")
- else:
- print("1 is equal to 2")
3. 循环 / 迭代器
在 Python 中, 我们有多种迭代的方式, 我在这里说两种:
While 循环: 当逻辑表达式为 true 的时候, while 下缩进的代码块就会被循环执行. 所以下面的代码片段, 将会从 1 打印到 10.
- num = 1
- while num <= 10:
- print(num)
- num += 1
上面这种循环方式, 需要一个循环条件, 如果循环条件是 true, 就会继续进行迭代, 在上面的例子中, 当 num 变成 11 的时候, 循环条件就会等于 False"
再看看下面的基础代码块, 以便于理解:
- loop_condition = True
- while loop_condition:
- print("Loop Condition keeps: %s" %(loop_condition))
- loop_condition = False
只要循环条件为 True, 就会被一直循环执行, 直到循环条件变成 False
For 循环: 与其他语言一样, 这用于计次循环, 它循环的次数, 取决于后面那个 range 方法.
range, 代表从在循环里, 它用于表示从 x 到 n, 如下, 就是从 1 到 11, 第三个参数可空, 意思是每次递进的加数, 默认每循环一次给 i 加 1, 填 2 的话, 就给 i 加 2
- for i in range(1, 11):
- print(i)
列表: 集合 | 数组 | 数据结构
想象一下, 你想把整数 1 存储在一个变量中. 但也许现在你想要存储 2 和 3,4,5 ...
我是否有另一种方法来存储我想要的所有整数, 但不是以百万计的变量? 你猜对了 -- 确实有另一种方法来存储它们.
List 是一个可以用来存储一列值的集合(比如你想要的这些整数). 那么让我们使用它:
my_integers = [1, 2, 3, 4, 5]
这真的很简单, 我们创建了一个数组并将其存储到 my_integer 里.
但是也许你在问: 『 我怎样才能从这个列表中获得值? 』
很好的问题. List 有一个叫做索引的概念. 第一个元素获取索引 0 (零). 第二个取 1 , 依此类推. 明白了吧.
为了使其更清楚, 我们可以用它的索引来表示数组和每个元素. 我可以画出来:
使用 Python 语法, 它也很容易理解:
- my_integers = [5, 7, 1, 3, 4]
- print(my_integers[0]) # 5
- print(my_integers[1]) # 7
- print(my_integers[4]) # 4
想象一下现在你不想存储整数了. 你只是想存储字符串, 就像你亲戚名字的列表一样. 看起来像这样:
- relatives_names = [
- "Toshiaki",
- "Juliana",
- "Yuji",
- "Bruno",
- "Kaio"
- ]
- print(relatives_names[4]) # Kaio
它的工作方式与整数相同, 漂亮.
我们刚刚了解到 Lists 索引是如何工作的. 但是我仍然需要告诉你如何将一个元素添加到 List 数据结构(一个项目到列表).
添加一个值到 List 最常见的方法是 append . 让我们看看他是如何工作的:
- bookshelf = []
- bookshelf.append("The Effective Engineer")
- bookshelf.append("The 4 Hour Work Week")
- print(bookshelf[0]) # The Effective Engineer
- print(bookshelf[1]) # The 4 Hour Work Week
append 非常的简单. 您只需要将元素 (例如『 The Effective Engineer 』) 作为『 append 』参数应用即可.
那么, 关于 Lists 到这里就结束了, 让我们来谈谈另一个数据结构.
字典: 键 - 值 数据结构
现在我们知道 Lists 使用整数来索引. 但是如果我们不想使用整数来索引呢? 一些其他的数据结构可以使用数字, 字符串或者其他的类型来做索引.
让我们来学习 Dictionary 数据结构. Dictionary 是一个键值对集合. 它长下面这样:
- dictionary_example = {
- "key1": "value1",
- "key2": "value2",
- "key3": "value3"
- }
键用来索引到值. 那么我们如何访问 Dictionary 的值呢? 你猜对啦? 6?6---?6?6 使用键. 试一下吧:
- dictionary_tk = {
- "name": "Leandro",
- "nickname": "Tk",
- "nationality": "Brazilian"
- }
- print("My name is %s" %(dictionary_tk["name"])) # My name is Leandro
- print("But you can call me %s" %(dictionary_tk["nickname"])) # But you can call me Tk
- print("And by the way Im %s" %(dictionary_tk["nationality"])) # And by the way Im Brazilian
我创建了一个关于我的 Dictionary. 我的名字, 昵称和国籍. 这些属性是 Dictionary 的键.
我们知道访问 List 使用下标, 我们在这也使用下标 ( Dictionary 中的键的内容) 来访问存在 Dictionary 中的值.
在例子中, 我打印出了存在 Dictionary 中的所有关于我的短语. 非常简单滴~?
另一件关于 Dictionary 非常帅气的事情就是我们可以使用任何东西来做为字典的值. 在我创建的 Dictionary 中, 我想添加键为 "age" 且值为我的整数年龄进去:
- dictionary_tk = {
- "name": "Leandro",
- "nickname": "Tk",
- "nationality": "Brazilian",
- "age": 24
- }
- print("My name is %s" %(dictionary_tk["name"])) # My name is Leandro
- print("But you can call me %s" %(dictionary_tk["nickname"])) # But you can call me Tk
- print("And by the way Im %i and %s" %(dictionary_tk["age"], dictionary_tk["nationality"])) # And by the way Im Brazilian
这里我们有一个键 (age) 值 (24) 对 使用字符串来作为键, 整数来作为值.
像我们学习 Lists 一样, 让我们来学习如何在 Dictionary 中添加元素. 在 Dictionary 中, 一个键指向一个值是很重要的. 这就是为什么我们在添加元素的时候讨论它:
- dictionary_tk = {
- "name": "Leandro",
- "nickname": "Tk",
- "nationality": "Brazilian"
- }
- dictionary_tk[age] = 24
- print(dictionary_tk) # {
- nationality: Brazilian, age: 24, nickname: Tk, name: Leandro
- }
我们只需要指定一个值到 Dictionary 的键上. 一点也不复杂, 484 啊?
迭代: 循环 Python 中的数据结构
当我们在学习 Python 基础时, 会发现列表的迭代是一件十分简单的事情 , 通常我们 Python 开发者会使用 For 来循环迭代它. 现在让我们尝试一下:
- bookshelf = [
- "The Effective Engineer",
- "The 4 hours work week",
- "Zero to One",
- "Lean Startup",
- "Hooked"
- ]
- for book in bookshelf:
- print(book)
如你所见我们已经对书架中的书进行了 for 操作, 我们输出打印了其中的书(当然你可以在循环中对它们做任何事情). 简单而又直观, 这就是 Python.
同样对于哈希类型的数据结构, 比如像是 Python 中的字典, 我们同样也可以对其使用 for 循环进行迭代操作, 但是此时我们则需要用到 key:
- dictionary = {
- "some_key": "some_value"
- }
- for key in dictionary:
- print("%s --> %s" %(key, dictionary[key]))
- # some_key --> some_value
这是一个循环字典类型变量的小例子, 对于 dictionary 变量我们使用 for 循环操作其中的 key, 接着我们打印输出他的 key 以及其相对应匹配的 value 值.
当然我们还有另外一种方法去实现它, 就是去使用 iteritems:
- dictionary = {
- "some_key": "some_value"
- }
- for key, value in dictionary.items():
- print("%s --> %s" %(key, value))
- # some_key --> some_value
你看我们已经命名了两个参数 key,value, 但这并不是必须的, 你甚至可以给它们起任何一个名字 ^.^, 让我们来看一下:
- dictionary_tk = {
- "name": "Leandro",
- "nickname": "Tk",
- "nationality": "Brazilian",
- "age": 24
- }
- for attribute, value in dictionary_tk.items():
- print("My %s is %s" %(attribute, value))
- # My name is Leandro
- # My nickname is Tk
- # My nationality is Brazilian
- # My age is 24
哈哈, 可以看到我们已经使用了 attribute 作为了 Dictionary 的 key 参数, 代码运行十分正确. 赞!
类型与对象
一点基础理论:
对象代表现实世界中像轿车, 狗, 自行车这些事物. 对象具有数据和行为两个主要特征.
在面向对象编程中, 我们把数据当作属性, 把行为当作方法. 即:
数据 → 属性 和 行为 → 方法
类型是创造单个对象实例的蓝本. 在现实世界中, 我们经常发现很多对象实例拥有相同的类型, 比如轿车. 他们都具有相同的构造和模型(具有发动机, 轮子, 门等等). 每辆车都是根据同一张设计图制作的, 并且具有相同的组成部分.
Python 的面向对象编程模式: ON
Python, 作为一门面向对象编程的语言, 具有类和对象的概念.
类是蓝图, 对象是模型.
同样, 一个类, 它只是一个模型, 或者一种定义属性和行为的方法(正如我们在理论部分所讨论的). 例如, 车辆类有自己的属性, 定义什么是车辆. 车轮的数量, 能源的类型, 座位容量和最大速度都是车辆的属性.
考虑到这一点, 让我们看看类的 Python 语法:
- class Vehicle:
- pass
我们用一个类声明来定义类? 6?6, 仅此而已. 很简单, 不是吗?
对象是一个类的实例, 我们用命名类来创建一个实例.
- car = Vehicle()
- print(car) # <__main__.Vehicle instance at 0x7fb1de6c2638>
这里'car' 是'Vehicle' 类的一个对象(或者说实例).
记住, 我们的'Vehicle' 类有四个属性: 轮子数量, 能源类型, 座位容量, 和最大速度. 我们创建一个'Vehicle' 对象时设置所有这些属性 . 所以在这里, 我们定义我们的类初始化时要接收数据时:
- class Vehicle:
- def __init__(self, number_of_wheels, type_of_tank, seating_capacity, maximum_velocity):
- self.number_of_wheels = number_of_wheels
- self.type_of_tank = type_of_tank
- self.seating_capacity = seating_capacity
- self.maximum_velocity = maximum_velocity
我们使用了'init'方法. 我们称它为构造方法. 所以创建'vehicle' 对象时可以定义这些属性. 假设我们喜欢 Tesla Model S, 我们要创建这种对象. 它有 4 个轮子, 使用电能, 有 5 个座位, 最大时速 250km/h (155mph)
tesla_model_s = Vehicle(4, electric, 5, 250)
4 个 "轮子"+ 电能 "能源"+5 个 "座位"+250km/h"最大速度".
所有属性都设置完成了. 但是我们如何获取这些属性值? 我们发送一个消息到对象来问他们. 我们称之为方法. 方法是对象的行为. 让我们来实现它:
- class Vehicle:
- def __init__(self, number_of_wheels, type_of_tank, seating_capacity, maximum_velocity):
- self.number_of_wheels = number_of_wheels
- self.type_of_tank = type_of_tank
- self.seating_capacity = seating_capacity
- self.maximum_velocity = maximum_velocity
- def number_of_wheels(self):
- return self.number_of_wheels
- def set_number_of_wheels(self, number):
- self.number_of_wheels = number
这里创建了两个方法: number_of_wheels 和 set_number_of_wheels. 我们称它为 获取 & 设置. 因为第一个获取了属性值, 然后第二个设置了一个新的属性值.
Python 中, 我们可以用 "@property" ("decorator") 去定义 "getters" 和 "setters". 请看以下代码:
- class Vehicle:
- def __init__(self, number_of_wheels, type_of_tank, seating_capacity, maximum_velocity):
- self.number_of_wheels = number_of_wheels
- self.type_of_tank = type_of_tank
- self.seating_capacity = seating_capacity
- self.maximum_velocity = maximum_velocity
- @property
- def number_of_wheels(self):
- return self.number_of_wheels
- @number_of_wheels.setter
- def number_of_wheels(self, number):
- self.number_of_wheels = number
同时, 我们可以使用这些方法作为属性:
- tesla_model_s = Vehicle(4, electric, 5, 250)
- print(tesla_model_s.number_of_wheels) # 4
- tesla_model_s.number_of_wheels = 2 # setting number of wheels to 2
- print(tesla_model_s.number_of_wheels) # 2
这个与定义方法有些许不同. 这些方法的工作机制与属性不同. 例如, 当我们设置轮子数量时, 我们需要把 2 赋值给一个变量, 只需要设置 "number_of_wheels" 的值为 2. 这是一种写 "pythonic", "getter","setter" 代码的方法.
而且同时我们也可以使用其他方法, 比如 "make_noise" 方法. 请看下面的例子.
- class Vehicle:
- def __init__(self, number_of_wheels, type_of_tank, seating_capacity, maximum_velocity):
- self.number_of_wheels = number_of_wheels
- self.type_of_tank = type_of_tank
- self.seating_capacity = seating_capacity
- self.maximum_velocity = maximum_velocity
- def make_noise(self):
- print(VRUUUUUUUM)
当我们调用这个方法时, 它返回字符串 "VRRRRUUUUM".
- tesla_model_s = Vehicle(4, electric, 5, 250)
- tesla_model_s.make_noise() # VRUUUUUUUM
封装: 信息隐藏
封装是一种限制直接访问对象数据和方法的机制. 但是它加快了对象方法中数据的访问.
"封装可以在定义中隐藏数据和函数成员, 意味着从外部隐藏了对象定义中的内部描述"--- Wikipedia
对象从外部隐藏了其内部描述. 只有对象可以与它的内部数据进行交互.
首先, 我们需要了解 "public" 和 "non-public" 变量实例的工作机制.
Public 变量实例
对于一个 Python 类型, 我们可以使用构造方法初始化一个公共变量实例. 我们看这个:
通过构造方法:
- class Person:
- def __init__(self, first_name):
- self.first_name = first_name
这里我们使用 "first_name" 的值作为一个参数传递给公共变量实例.
- tk = Person(TK)
- print(tk.first_name) # => TK
在类中:
- class Person:
- first_name = TK
这里, 我们不需要使用 "first_name" 作为一个参数, 所有的对象实例都有一个用 "TK" 初始化的类属性.
- tk = Person()
- print(tk.first_name) # => TK
漂亮. 我们已经学习到可以使用公共变量实例和类型属性. 另一件关于 "public" 部分有趣的事情是我们可以管理它的变量的值. 我的意思是什么呢? 我们的对象可以管理它的变量值: 获取和设置变量值.
记住 "Person" 类, 我们想要设置另一个值给它的 "first_name" 变量:
- tk = Person(TK)
- tk.first_name = Kaio
- print(tk.first_name) # => Kaio
好了, 我们刚刚设置了另一个值 ("kaio") 给对象变量 "first_name", 并且它更新了它的值. 就是这么简单, 因为这个 "public" 变量, 我们可以这样做.
Non-public 变量实例
"在这里, 我们不用'私有'来形容 , 因为在 Python 中没有真正" 私有 "的属性(避免了一般情况下不必要的工作)."---?6?6PEP 8
和公共变量实例一样, 我们可以在构造函数或类内部定义非公共变量实例. 语法上的差异是: 对于非公共变量实例, 我们在变量名前加一道下划线(_).
"在 Python 中, 无法从内部访问'私有'变量实例的对象是不存在的. 但是, 大多数 Python 代码遵循一个惯例: 一个名字前有一道下划线的对象应该被认为是 API 中非公共的部分, 例如_spam, 无论它是一个函数, 方法或是数据成员."?6?6---?6?6Python Software Foundation
这是一个例子:
- class Person:
- def __init__(self, first_name, email):
- self.first_name = first_name
- self._email = email
看到 email 变量了吗? 这就是定义一个非公共变量的方法.
- tk = Person(TK, tk@mail.com)
- print(tk._email) # tk@mail.com
所谓非公共变量只是一个惯例, 没有机制禁止我们从外部访问并更新它. 但按照惯例, 我们应该把它作为 API 中非公共的部分来对待.
在类内部, 我们通常使用方法来操作 "非公共变量", 让我们实现两个方法 (email 和 update_email) 来理解.
- class Person:
- def __init__(self, first_name, email):
- self.first_name = first_name
- self._email = email
- def update_email(self, new_email):
- self._email = new_email
- def email(self):
- return self._email
现在, 我们可以通过这些方法来访问, 更新非公共变量.
- tk = Person(TK, tk@mail.com)
- print(tk.email()) # => tk@mail.com
- tk._email = new_tk@mail.com
- print(tk.email()) # => tk@mail.com
- tk.update_email(new_tk@mail.com)
- print(tk.email()) # => new_tk@mail.com
我们以 first_name TK 和 email tk@mail.com 初始化一个 Person 对象.
通过方法访问非公共变量 email, 并打印出来.
从类外部直接设置一个新的 email.
我们应该把非公共变量作为 API 中非公共的部分来对待.
通过实例方法更新非公共变量 email.
成功! 我们可以通过预设的方法来更新它.
公共方法
通过 公共方法, 我们也可以在我们类的外部使用这些方法了:
- class Person:
- def __init__(self, first_name, age):
- self.first_name = first_name
- self._age = age
- def show_age(self):
- return self._age
让我们来试下:
- tk = Person(TK, 25)
- print(tk.show_age()) # => 25
赞 -- 用起来没有任何问题.
非公共方法
但是通过 非公共方法 我们却无法做到这一点. 我们先来实现一个同样的 Person 类, 不过这回我们加个下划线 (_) 来定义一个 show_age 的非公共方法.
- class Person:
- def __init__(self, first_name, age):
- self.first_name = first_name
- self._age = age
- def _show_age(self):
- return self._age
那么现在, 我们来试着通过我们的对象调用这个 非公共方法:
- tk = Person(TK, 25)
- print(tk._show_age()) # => 25
我们可以访问并且更新它. 非公共方法 只是一类约定俗成的规定, 并且应当被看做接口中的非公共部分.
关于我们该怎么使用它, 这有个例子:
- class Person:
- def __init__(self, first_name, age):
- self.first_name = first_name
- self._age = age
- def show_age(self):
- return self._get_age()
- def _get_age(self):
- return self._age
- tk = Person(TK, 25)
- print(tk.show_age()) # => 25
这里我们有一个 _get_age 非公共方法和一个 show_age 公共方法. show_age 可以由我们的对象调用 (在类的外部) 而_get_age 只能在我们类定义的内部使用(内部 show_age 方法). 但是再次强调下, 这只是个约定俗成的规定.
封装总结
通过封装我们可以从外部隐藏对象的内部表示.
继承: 行为和特征
某些对象具有共同点: 如行为和特征.
例如, 我从我父亲那里继承了一些特征和行为. 我继承了他的眼睛和头发作为特征, 继承了他的急躁和内向作为行为.
在面向对象编程中, 类能够从其他类中继承特征 (数据) 和行为(方法).
让我们看另外一个例子.
假定一辆车. 轮子的数量, 载客量和最高时速是车的所有属性. 那么我们可以认为 ElectricCar 类从这个 Car 类中继承了这些属性.
- class Car:
- def __init__(self, number_of_wheels, seating_capacity, maximum_velocity):
- self.number_of_wheels = number_of_wheels
- self.seating_capacity = seating_capacity
- self.maximum_velocity = maximum_velocity
我们的 Car 类实现之后:
- my_car = Car(4, 5, 250)
- print(my_car.number_of_wheels)
- print(my_car.seating_capacity)
- print(my_car.maximum_velocity)
一旦初始化后, 我们可以使用所有已创建的实例变量. 很好.
在 Python 中我们可以将父类作为子类定义时的参数. 一个 ElectricCar 类能从之前的 Car 类中继承.
- class ElectricCar(Car):
- def __init__(self, number_of_wheels, seating_capacity, maximum_velocity):
- Car.__init__(self, number_of_wheels, seating_capacity, maximum_velocity)
简单如上. 我们不需要实现任何其他的方法, 因为这个类已经有了(继承自 Car 类). 让我们确认一下:
- my_electric_car = ElectricCar(4, 5, 250)
- print(my_electric_car.number_of_wheels) # => 4
- print(my_electric_car.seating_capacity) # => 5
- print(my_electric_car.maximum_velocity) # => 250
漂亮.
就到这里!
关于 Python 基础, 我们学会了很多:
变量
分支语句
循环语法
列表: 集合 | 数组
字典: 键值对的集合
如何迭代这些数据结构
对象和类
用属性作为对象的数据
用方法作为对象的行为
getters,setters 和 property 装饰器
封装: 信息隐藏
继承: 行为和特征
恭喜! 你完成了 Python 的这段密集的内容.
坚持学习, 坚持编程, 祝你玩得开心!
来源: http://www.bubuko.com/infodetail-2846101.html