視頻課程鏈接:http://edu.51cto.com/course/14859.html
Python基礎,主講:湯小洋
一、Python簡介
1. Python是什麼?
Python是一種面向對象的解釋型計算機程序設計語言,由荷蘭人Guido van Rossum(龜叔)於1989年發明,第一個公開發行版發行於1991年。
誕生:1989年聖誕節期間,在阿姆斯特丹,Guido爲了打發聖誕節的無趣,決心開發一個新的腳本解釋程序,即Python(TIOBE編程語言排行榜)
作用:開發網站、後臺服務、工具腳本、爬蟲、數據分析、人工智能等
特點:
- 優點:簡單(定位:簡單、優雅、明確)、代碼量少(人生苦短 我用python)、功能強大(大量的第三方庫)
- 缺點:運行速度慢、代碼不能加密
- 補充:Python是一門解釋型語言,不需要編譯,類似於PHP,不同於Java、C#等編譯型語言
2. 安裝Python
Python是跨平臺的,執行Python代碼需要解釋器
版本:2.x、 3.x
安裝步驟:
-
Windows
-
Linux
mkdir python # 創建Python的安裝目錄 tar zxf Python-3.6.5.tgz # 解壓縮 cd Pyton-3.6.5 ./configure --prefix=/home/soft01/python # 配置,指定安裝位置 make # 編譯 make install # 安裝 cd /home/soft01/python/bin ./python3 # 將python路徑添加到PATH變量中 vi ~/.bashrc export PATH=/home/soft01/python/bin:$PATH source ~/.bashrc
二、第一個Python程序
1. 使用Python交互模式
執行python
命令,就進入Python交互模式,提示符>>>
,輸入exit()
退出交互模式
>>> 3+8
11
>>> print('Hello World')
Hello World
>>> name='tom'
>>> print(name)
tom
>>>exit()
2. 使用文本編輯器
建議使用sublime或notepad++等,不要使用windows自帶的記事本(會自動在文件的開頭添加特殊字符)
步驟:
-
創建Python腳本文件,以.py結尾
# -*- coding: utf-8 -*- # 這是註釋,第一個Python程序 print('Hello World') name='唐伯虎' print(name)
注:如果腳本中有中文,可能會報錯,需要在文件的第一行添加一個特殊的註釋
-
運行腳本
python hello.py
-
直接執行腳本
在Linux和Mac中可以直接執行.py腳本文件,方法:
- 在文件的第一行添加一個特殊的註釋:
#!/usr/bin/env python3
- 爲文件添加執行權限:
chmod a+x hello.py
- 直接執行腳本文件:
./hello.py
- 在文件的第一行添加一個特殊的註釋:
3. 使用IDE工具
PyCharm,JetBrain公司出口
使用步驟:
-
創建包
包中必須存在一個
__init__.py
文件,用於標識這是一個包 -
創建Python腳本
#!/usr/bin/env python3 # -*- coding: utf-8 -*- __author__ = '湯小洋' # 輸出,使用print() print('hello world') name = 'alice' print(name)
4. 基本使用
輸入和輸出
- 使用print()
- 使用input()
註釋:
- 單行註釋,以
#
開頭 - 多行註釋,使用三對單引號或三對雙引號
編碼規範:
- 不要在行尾加分號
- 大小寫敏感
- 適應添加空格、空行,使代碼佈局更優雅、美觀、合理
- 使用縮進來表示代碼塊
三、Python基礎
1. 變量和數據類型
變量:
- 定義變量時不需要指定變量的類型,直接爲變量賦值即可
- 變量名要符合命名規範
數據類型:整型、浮點型、字符串、布爾、空值等
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
__author__ = '湯小洋'
'''
數據類型:整型、浮點型、字符串、布爾、空值等
'''
# 整型int
a = 3454566666666666666
print(a)
print(type(a))
# 浮點型float
b = 12.5
print(b, type(b))
# 字符串str,定義字符串可以使用單引號或雙引號(推薦用單引號)
c = 'ccc'
d = "ddd"
print(c, type(c))
print('張三說:"今晚吃雞嗎?"')
# 字符串有多行時可以使用三對單引號,表示多行內容
e = '''
welcome
to
itany
'''
print(e)
print(type(e))
# 布爾bool,取值:True、False
f = True
print(f, type(f))
g = 5 < 3
print(g)
print(5 + False) # True表示1,False表示0
# 空值 NoneType
h = None
print(h, type(h))
2. 字符串
類型轉換
# 將字符串轉換數值
a = '25'
b = int(a)
print(type(a), type(b))
c = '12.5'
d = float(c)
print(type(c), type(d))
# 將數值轉換爲字符串
print('hello ' + str(25)) # 數值類型不能直接和字符中進行拼接,需要進行類型轉換
字符串常用方法
string = ' hello world '
print(string.islower())
print(string.isupper())
print(string.capitalize())
print(string.index('llo'))
print(string)
print(string.strip()) # 類似於java中的trim
print(len(string)) # 調用len()函數獲取長度
切片
name = 'tom cruise'
print(name[0])
print(name[4], name[len(name) - 1], name[-1])
print(name[1:5]) # 獲取索引爲[1,5)的字符
print(name[:5]) # 表示從頭獲取
print(name[2:]) # 表示獲取到末尾
print(name[1:8:2]) # 索引爲[1,8)的字符,每兩個取一個
print(name[::2]) # 所有字符,每兩個取一個
格式化
# 格式化字符串,在字符串中指定佔位符
# 方式1:使用%運算符,%s表示任意字符,%d表示整數,%f表示浮點數
name = 'tomaaaa'
age = 20
height = 180.5
print('大家好,我叫' + name + ',年齡:' + str(age) + ',身高:' + str(height))
print('大家好,我叫%2.4s,年齡:%d,身高:%.2f' % (name, age, height)) # 2.4s表示字符串長度爲2-4位,.2f表示保留兩位小數
print('當前時間:%d年-%02d月-%d日' % (2018, 5, 14)) # 指定月份爲兩位,不足兩位則補0
# 方式2:使用format()方法,使用{}表示佔位符
print('大家好,我叫{0},年齡:{1},身高:{2:.2f}'.format(name, age, height))
print('大家好,我叫{name},年齡:{age},身高:{height}'.format(age=age, name=name, height=height))
# 方式3:在字符串前面添加一個f,使用{變量名}來嵌入變量
print(f'大家好,我叫{name},年齡:{age},身高:{height}')
3. 運算符
算術運算符、比較運算符、賦值運算符、邏輯運算符、位運算符、條件運算符、成員運算符、身份運算符
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
__author__ = '湯小洋'
'''
Python中支持的運算符:
1.算術運算符
+ - * / % // **
不支持自增++和自減--
2.比較運算符
> < >= <= == !=或<>
3.賦值運算符
= += -= *= /+ %= **=
4.邏輯運算符
and or not
5.條件運算符,也稱三目運算符
語法:條件爲真時的結果 if 條件 else 條件爲假時的結果
6.位運算符
與& 或| 非~ 異或^ 左移<< 右移>>
7.成員運算符
in
not in
8.身份運算符
is
is not
'''
# 1.算術運算符
print(3 + 5)
print(3 * 5)
print(30 * '-') # 乘法可以用於字符串
print(5 % 3)
print(5 / 3) # 除法,有小數
print(5 // 3) # 除法,取整
print(2 ** 3) # 冪
print(pow(2, 3))
i = 5
i = i + 1
print(i)
print('*' * 80)
# 2.比較運算符
j = 5
print(j > 2)
print(10 > j > 1) # 支持此寫法
print('abc' > 'acd') # 可以用於字符串的比較,比較的是字符串的Unicode編碼
# 3.賦值運算符
a = 10
a += 5 # 等價於a= a+5
print(a)
# 4.邏輯運算符
print(True and False)
print(5 > 2 or 4 < 1)
print(not 5 > 2)
x = 0 # 0 表示False,非0表示True
y = 8
print(x and y) # 如果x爲True,則返回y;否則返回x
print(x or y) # 如果x爲True,則返回x;否則返回y
print(not x) # 如果x爲True,則返回False,否則返回True
# 5.條件運算符,也稱三目運算符
print('aaa' if 5 < 2 else 'bbb')
# 6.位運算符
a = 5 # 00000101
b = 8 # 00001000
print(a & b) # 兩位都是1才爲1,否則爲0
print(a | b) # 只要有一位爲1,則爲1,否則爲0
print(~a) # 如果爲1,則爲0,如果爲0,則爲1
print(a ^ b) # 如果兩位相同,則爲0,不同爲1
print(b >> 2) # 二進制的所有位都向右移2位
# 7.成員運算符
c = [3, 5, 12, 15, 7, 2]
d = 5
print(d not in c)
# 8.身份運算符
m = [1, 3, 5, 7]
n = [1, 3, 5, 7]
x = n
print(m is n)
print(x is n)
'''
is 和 == 的區別
is 判斷兩個變量是否引用同一個對象
== 判斷兩個變量的值是否相等
'''
print(m == n)
4. 列表和元組
列表list是一種有序的集合,用來存儲多個值,可以向列表中添加或刪除元素
元組tuple與list很類似,也是用來存儲多個值,但tuple中的元素只能在定義時初始化,初始化後就無法再修改
總結:列表list和元組tuple都是Python內置的一種集合,一個可變的,一個是不可變的
# ---列表list
# 定義列表,使用[]
names = ['tom', 'jack', 'alice', 'mike']
print(names)
print(type(names))
# 獲取/設置元素
print(names[1], names[:3])
names[0] = 'lucy'
print(names)
# 追加元素
names.append('zhangsan')
# 在指定位置插入元素
names.insert(1, 'lisi')
# 刪除元素
names.remove('jack')
# 彈出元素
print(names.pop(0))
# 獲取元素個數
print(len(names))
# 可以存儲不同類型的數據
names.append(25) # 不建議
names.append(True)
print(names)
print('-' * 80)
# ------元組tuple
# 定義元組,使用()
nums = (3, 8, 13, 25, 38, 250)
print(nums)
print(type(nums))
print(nums[2], nums[-1])
print(nums[1:3])
# 解構賦值
# a = nums[0]
# b = nums[1]
# c = nums[2]
# d = nums[3]
# e = nums[4]
# f = nums[5]
a, b, c, d, e, f = nums
print(a, b, c, d, e, f)
5. 條件判斷
根據條件進行判斷,從而執行不同的操作
使用if...elif...else
語句
6. 循環
重複性的執行某個操作,稱爲循環
兩種:
- while循環
- for...in循環
# ----while循環
# 計算1到100的和
i = 1
sum = 0
while i <= 100:
sum += i
i += 1
print(sum)
# ----for...in循環
names = ['tom', 'jack', 'alice', 'mike']
for name in names:
print(name, end=',')
print()
# 使用range()函數生成一個序列
for i in range(1, 100, 2): # 生成一個[1,100)的整數序列,步長爲2
print(i, end=',')
print()
# 計算1到100的和
sum = 0
for i in range(1, 101):
sum += i
print(sum)
break和continue關鍵字
7. 字典和集合
dict全稱dictionary,使用鍵-值(key-value)存儲數據,在其他語言中一般稱爲map
set是無序的,不允許重複
# ----字典
# 定義dict,使用大括號{},與js中的json很類似
scores = {'tom': 98, 'jack': 100, 'alice': 60}
print(scores)
print(type(scores))
# 獲取
print(scores['jack'])
print(scores.get('alice'))
# 添加/設置
scores['lucy'] = 89
scores['tom'] = 100
# 彈出(刪除)
print(scores.pop('tom'))
# 判斷是否存在指定的key
print('alice' in scores)
print(scores)
# 遍歷
print(scores.keys())
print(scores.values())
print(scores.items())
for k in scores.keys():
print(k, scores[k])
print('-' * 80)
for v in scores.values():
print(v)
print('-' * 80)
for k, v in scores.items():
print(k, v)
print('-' * 80)
# -----set集合
# 定義set,使用大括號{}
# s = {3, 12, 5, 7, 34, 12, 3}
nums = [4, 23, 1, 23, 4, 23]
s = set(nums) # 調用set()函數將list轉換爲set,去除重複值
print(s)
print(type(s))
# 添加
s.add(666)
s.add(1)
# 刪除
s.remove(1)
print(s)
# 遍歷
for i in s:
print(i)
四、函數
函數是實現特定功能的代碼段的封裝,在需要時可以多次調用函數來實現該功能
1. 內置函數
Python內置了許多非常有用的函數,可以直接調用
2. 自定義函數
語法:
def 函數名(形參1,形參2,...):
函數體
注意:
- 函數名可以包含數字、字母、下劃線,但不能以數字開頭
- 如果函數有返回值,使用return關鍵字
- 定義函數後函數中的代碼並不會執行,需要調用函數纔會執行
# 定義函數,使用def
def calc(num1, num2): # 必選參數,也稱爲位置參數,不能省略
res = num1 + num2
return res
# print(calc(3, 5)) # 調用函數
# 參數類型檢查
def my_abs(x):
# 可以爲函數添加文檔註釋,也稱爲文檔字符串doc string
"""
計算絕對值
:param x: 參數
:return: 返回x的絕對值
"""
# 對參數類型進行檢查
if not isinstance(x, (int, float)):
raise TypeError('參數類型不正確,只能爲數值類型') # 拋出異常
if x >= 0:
return x
else:
return -x
# print(my_abs('aaa'))
# print(help(my_abs))
# 默認參數,即有默認值的參數
def my_pow(x, y=2):
if y == 0:
return 1
res = x
for i in range(y - 1):
res *= x
return res
# print(my_pow(5))
# 可變參數,使用*號,表示參數個數是可變的
def my_sum(x, *y):
print(x)
print(y) # 接收到的實際上是一個tuple
# my_sum(3, 5, 8, 12, 4)
# 不建議下面的這種寫法,建議將必選參數放在最前面
def my_sum2(*y, x):
print(y)
print(x)
# my_sum2(12, 4, 2, 7, x=9) # 必選參數在後面時需要指定參數名
# 對於可變參數,可以直接傳入list或tuple,只需要在參數前添加一個*
nums = [12, 4, 2, 64, 23, 9]
# my_sum(4, nums[0], nums[1], nums[2], nums[3], nums[4], nums[5])
# my_sum(4, *nums)
# 關鍵字參數,使用**,也表示參數個數是可變的,但傳遞的是帶名稱的參數
def f1(x, **y):
print(x)
print(y) # 接收到的實際上一個dict
# f1(3, a=5, b=9, c=18)
# 對於關鍵字參數,可以直接傳入一個dict,只需要在參數前添加**
user = {'id': 1001, 'name': 'tom', 'age': 18}
# f1(4, id=user['id'], name=user['name'], age=user['age'])
# f1(4, **user)
# 命名關鍵字參數,限制關鍵字參數的名字,使用*分隔,*號後面的參數表示命名關鍵字參數
def f2(x, *, name, age):
print(x)
print(name)
print(age)
# f2(4, name='alice', age=20)
# 接收任意參數
def f3(*args, **kwargs):
print(args)
print(kwargs)
f3(1, 43, 'aaa', name='alice', age=20)
# 空函數,表示以後再實現
def empty():
pass # 使用pass
# 函數的返回值,返回多個值
def f1():
name = 'tom'
age = 20
sex = 'male'
return name, age, sex
# print(f1()) # 返回值實際上是一個tuple
a, b, c = f1()
# print(a, b, c)
# 函數的返回值,返回一個函數,即將函數作爲返回值
def f2(x):
print(111)
z = 6
def f3(y):
print(x * y + z) # 內部函數使用了外部函數的參數或局部變量,稱爲閉包
return f3
# fn = f2(3)
# fn(5)
# 遞歸函數:一個函數在內部調用自身,這個函數就是遞歸函數
# 計算x的y次方,如計算2的5次方
def calc(x, y):
# 常規方式
# if y == 0:
# return 1
# i = 1
# res = x
# while i < y:
# res *= x
# i += 1
# return res
# 遞歸方式
# 2*2*2*2*2=2*(2*2*2*2)=2*(2*(2*2*2))=
if y == 0:
return 1
else:
return x * calc(x, y - 1) # 不停的調用自己,遞歸太深可能會拋出棧溢出異常
print(calc(2, 99999999999999))
3. 變量作用域和命名空間
'''
變量作用域scope:指的是變量生效的區域
兩種作用域:
1.全局作用域
函數以外的區域都是全局作用域
在全局作用域中定義的變量,都是全局變量
2.函數作用域,也稱爲局部作用域
函數內的區域,每調用一次函數就會創建一個新的函數作用域
在函數作用域中定義的變量,都是局部變量
變量的查找順序:
先在當前作用域中查找,如果沒有則向上一級作用域中查找,直到查找全局作用域,如果還是沒有,則報錯
'''
a = 5 # 全局變量
if True:
c = 5 # 全局變量,在Python中沒有塊級作用域
def fn():
b = 8 # 局部變量
print('函數內部:a=', a)
print('函數內部:b=', b)
print('函數內部:c=', c)
fn()
print('函數外部:a=', a)
# print('函數外部:b=', b)
print('函數外部:c=', c)
x = 1
def f1():
x = 2
def f2():
x = 3
print(x)
print('-' * 80)
# global關鍵字
def fn2():
# a = 10 # 在函數中爲變量賦值時,默認都是爲局部變量賦值
# 如果希望在函數中修改全局變量,要使用global關鍵字來聲明變量
global a
a = 10
print('函數內部:a=', a)
fn2()
print('函數外部:a=', a)
print('*' * 80)
'''
命名空間namespace:指的是變量存儲的位置,每一個變量都要存儲在指定的命名空間中
每個作用域都有一個對應的命名空間
全局命名空間,用來存儲全局變量;函數命名空間,用來存儲函數中的變量
命名空間實際上就是一個字典dict,是一個專門用來存儲變量的字典
'''
# locals() 獲取當前作用域的命名空間
scope = locals() # 在全局作用域中調用locals(),獲取的就是全局命名空間
print(scope)
print(type(scope))
# 通過scope操作命名空間中的變量(不建議)
print(scope['a'])
scope['c'] = 666
scope['z'] = 'tom'
print(scope['c'])
print(scope['z'])
# print(z)
print('*' * 80)
def fn3():
a = 888
scope = locals() # 在函數中調用locals(),獲取到的是函數命名空間
scope['b'] = 222
print(scope)
print(scope['b'])
# globals() 可以在任意位置獲取全局命名空間
global_scope = globals()
print(global_scope)
print(global_scope['a'])
fn3()
4. 高級特性
迭代和列表生成式
# 導入模塊
import collections
'''
迭代:也稱爲遍歷,循環獲取每一個元素
'''
for i in ['tom', 'jack', 'alice']:
print(i, end=' ')
print()
for i in ('tom', 'jack', 'alice'):
print(i, end=' ')
print()
for i in {'name': 'tom', 'age': 18, 'sex': 'male'}.keys():
print(i, end=' ')
print()
for k, v in {'name': 'tom', 'age': 18, 'sex': 'male'}.items():
print(k, v)
for i in 'hello':
print(i)
# 判斷對象是否是可迭代的
print(isinstance('hello', collections.Iterable))
# 獲取索引和值
# 方式1:自己獲取索引
names = ['tom', 'jack', 'alice']
for i in range(len(names)):
print(i, names[i])
# 方式2:使用enumerate()函數,轉換爲索引-元素對
print(enumerate(names))
print(isinstance(enumerate(names), collections.Iterable))
for k, v in enumerate(names):
print(k, v)
print('-' * 80)
'''
列表生成式:用來創建list的生成式
'''
# 生成[0,99]的list
# nums = range(0, 100)
nums = list(range(0, 100)) # 轉換爲list
# print(nums, type(nums))
# print(isinstance(range(0, 100), collections.Iterable))
# for i in range(0, 100):
# print(i)
# 生成一個包含[1,100]之間所有3的倍數的list
# 方式1
# lst = []
# for i in range(1, 101):
# if i % 3 == 0:
# lst.append(i)
# 方式2
lst = [i for i in range(1, 101) if i % 3 == 0] # 等價於a = list(range(1, 101))
print(lst)
迭代器和生成器
'''
迭代器iterator:用來訪問集合元素的一種方式,可以記住迭代的位置
'''
nums = [3, 8, 12, 54, 2, 7]
it = iter(nums) # 調用iter()函數創建迭代器
print(type(it))
print(next(it)) # 調用next()函數獲取迭代器的下一個元素
print(next(it)) # 只能往前不能後退
# 使用for...in循環遍歷迭代器
for i in it:
print(i)
'''
生成器generator:在循環過程中依次計算獲取值的對象(節省空間、效率高)
創建生成器的方式:
方式1:把一個列表生成式的[]改成()
方式2:在函數中使用yield關鍵字,此時該函數就變成一個生成器函數
'''
# 方式1:把一個列表生成式的[]改成()
generator = (i for i in range(1, 100))
print(type(generator)) # generator類型
# 獲取生成器的下一個值
print(next(generator)) # 獲取時才生成值,類似於Oracle中sequence
print(next(generator))
print(next(generator))
# 使用for...in循環遍歷生成器
for i in generator:
print(i)
print('-' * 80)
# 方式2:在函數中使用yield關鍵字,此時該函數就變成一個生成器函數
def gen():
print('one')
yield 13
print('two')
yield 8
print('three')
yield 25
print('four')
yield 38
# 生成器函數與普通函數的執行流程不一樣:
# 普通函數是順序執行,執行到最後一行或遇到return時結束
# 生成器函數是在每次調用next()時執行,遇到yield語句就返回,下一次調用next()時會從上次返回的yield語句處繼續執行
g = gen() # generator類型
print(type(g))
print(next(g))
print(next(g))
# 使用for...in循環遍歷生成器
for i in g:
print(i)
高階函數
'''
高階函數:一個函數接收另一個函數作爲參數,這種函數稱爲高階函數
'''
nums = [12, -4, 3, -23, 65, 1, -234, 22]
# 定義一個函數,用來檢查數字是否大於5
def f1(x):
if x > 5:
return True
return False
# 自定義高階函數,用來過濾列表中的元素
def fn(fun, lst):
"""
將列表中所有符合條件的元素篩選出來,返回一個新列表
:param fun: 條件函數
:param lst: 要進行篩選的列表
:return: 返回新列表
"""
new_list = []
for i in lst:
if fun(i):
new_list.append(i)
return new_list
nums1 = fn(f1, nums)
print(nums1)
def f2(x):
return x % 2 == 0
print(fn(f2, nums))
# 內置高階函數 filter(),用於過濾序列
nums2 = filter(f1, nums)
print(list(nums2))
# 內置高階函數 map(),用於處理序列
def f3(x):
return x * x
nums3 = map(f3, nums)
print(list(nums3))
# 內置高階函數 sorted(),用於排序
print(sorted(nums))
print(sorted(nums,key=abs))
匿名函數和裝飾器
'''
匿名函數:沒有名字的函數,使用lambda關鍵字
'''
nums = [12, 4, 32, 5, 23, 7]
# def fn(x):
# return x * 2 + 1
nums_new = list(map(lambda x: x * 2 + 1, nums))
print(nums_new)
# 將匿名函數賦給變量(不建議)
a = lambda x: x + 1
print(a(2))
print('-' * 80)
'''
裝飾器:在代碼運行期間動態增加功能,稱爲裝飾器Decoration,類似於AOP
'''
# 定義一個裝飾器,爲函數添加打印日誌的功能
def log(fn):
def wrapper(*args, **kwargs):
print('開始執行%s()函數。。。' % fn.__name__)
res = fn(*args, **kwargs)
print('執行%s()函數結束。。。' % fn.__name__)
return res
return wrapper # 返回裝飾函數
@log
def even(lst):
for i in lst:
if i % 2 == 0:
print(i)
@log
def calc(num1, num2):
res = num1 + num2
return res
even([12, 34, 2, 5, 34, 21])
print(calc(3, 5))
五、面向對象
1. 定義類
語法:
class 類名:
類中成員
類中的成員:實例屬性、實例方法、類屬性、類方法、靜態方法等
# 定義一個類,使用class關鍵字
class Student:
# pass
# 類屬性:直接在類中定義的屬性,可以通過類或實例對象來訪問
hobby = '吃飯'
# 實例方法:將self作爲第一個參數的方法
def say_hi(self): # self表示當前類的實例,類似於java中的this
print('Hi:' + self.name)
def say_hello(self, username='無名氏'):
print('Hello:' + username)
# 類方法:使用@classmethod修飾的方法,將cls作爲第一個參數
@classmethod
def show(cls, msg): # cls表示當前類
print(msg, cls.hobby)
# 靜態方法:使用@staticmethod修飾的方法,沒有任何必選參數,不需要將cls作爲第一個參數
@staticmethod
def show2(msg):
print(msg, Student.hobby)
# 創建類的對象
stu1 = Student() # 創建Student類的一個實例
stu2 = Student()
print(stu1, type(stu1))
print(stu2, type(stu2))
a = 3
print(a, type(a))
b = int(5) # 創建int類的一個實例
c = str('hello') # 創建str類的一個實例
print(b, type(b))
# 爲對象綁定屬性
stu1.name = 'tom' # 實例屬性,通過實例對象添加的屬性
stu1.age = 20
stu2.name = 'alice'
stu2.sex = 'female'
stu2.height = 180.5
print(stu1.name, stu1.age)
print(stu2.name, stu2.sex, stu2.height)
# 訪問實例方法
stu1.say_hi() # 調用方法時無需傳遞self,由解析器調用時將對象作爲self自動傳入
stu2.say_hi()
stu1.say_hello('張三')
stu2.say_hello()
# 訪問類屬性
print(Student.hobby)
stu1.hobby = '睡覺' # 爲stu1添加了一個實例屬性,並不會改變類屬性hobby的值
print(stu1.hobby)
print(stu2.hobby) # 如果當前實例沒有hobby屬性,則會向上查找類屬性hobby
# 訪問類方法
Student.show('hello') # 調用方法時無需傳遞cls
stu1.show('Hello')
Student.show2('您好')
stu2.show2('你好')
2. 構造方法
__init__()
構造方法,在創建對象時會自動調用,可以用來初始化對象的屬性
class Student:
# 構造方法(函數),不支持重載
def __init__(self, name, age):
print('創建對象,執行構造方法。。。')
self.name = name
self.age = age
# 實例方法
def show(self):
print('姓名:%s,年齡:%d' % (self.name, self.age))
stu1 = Student('tom', 18)
print(stu1.name, stu1.age)
stu1.show()
3. 封裝、繼承、多態
封裝:隱藏對象中一些不希望被外部所訪問到的屬性,保證數據的安全
class Student:
# 定義私有屬性
__age = 18 # 以兩個下劃線開頭,表示對象的隱藏屬性,只能在類內部訪問
# 提供getter/setter方法
def get_age(self):
return self.__age
def set_age(self, age):
# 判斷數據是否有效
if 0 < age < 100:
self.__age = age
else:
self.__age = 18
stu1 = Student()
# print(stu1.__age) # 在類外部無法訪問私有屬性
stu1.set_age(28)
print(stu1.get_age())
# 其實Python會把私有屬性轉爲 _類名__屬性名(強烈不建議)
print(stu1._Student__age)
繼承:使一個類能夠獲取到其他類中的屬性和方法
# 定義一個Person類,父類(超類、基類)
class Person(object): # 如果省略了父類,則默認父類爲object
def __init__(self, name):
self.name = name
def run(self):
print('person:' + self.name + '正在奔跑。。。')
# 定義一個Student類,子類
class Student(Person): # 繼承自Person
def __init__(self, name, email):
# 調用父類的構造方法
# Person.__init__(name) # 方式1:直接指定父類的構造方法
super().__init__(name) # 方式2:使用super,推薦
self.email = email
# 定義子類特有的方法
def study(self):
print('student:' + self.name + '正在學習。。。')
def show(self):
print('姓名:%s,郵箱:%s' % (self.name, self.email))
# 重寫父類的方法
def run(self):
# super().run() # 調用父類的方法
print('student:' + self.name + '正在奔跑。。。。')
stu = Student('tom', '[email protected]')
stu.run() # 調用子類重寫後的方法
stu.study()
stu.show()
# 判斷一個對象是否是指定類的實例,即判斷對象的類型
print(isinstance(stu, Student))
print(isinstance(stu, Person))
# 判斷一個類是否是指定類的子類
print(issubclass(Student, Person))
print(issubclass(Student, object))
# object類是所有類的根類,默認所有類都繼承自object
print(stu.__doc__)
print(stu.__dict__)
多繼承
class A:
def a(self):
print('a')
class B:
def b(self):
print('b')
class C(A, B): # 繼承多個父類,以逗號隔開
def c(self):
print('c')
c = C()
c.a()
c.b()
c.c()
# 類的特殊屬性 __bases__ 可以用來獲取當前類的所有父類
print(C.__bases__)
多態:多種形態
class Animal:
def __init__(self, name):
self.name = name
def cry(self):
print('動物在叫。。。。')
class Dog(Animal):
def __init__(self, name, age):
super().__init__(name)
self.age = age
def cry(self):
print('狗在叫。。。。汪汪汪')
class Cat(Animal):
def __init__(self, name, sex):
super().__init__(name)
self.sex = sex
def cry(self):
print('貓在叫。。。喵喵喵')
# 一個對象可以以不同的形式去呈現,就是多態
def play(animal):
print(animal.name)
animal.cry()
dog = Dog('旺財', 2)
cat = Cat('貓咪', '公')
play(dog)
play(cat)
4. 魔術方法
在類中可以定義一些特殊的方法,稱爲魔術方法
特點:
- 都是以雙下劃線開頭,以雙下劃線結尾
- 不需要手動調用,在特定時機會自動執行
# 定義一個類
class Person(object):
def __init__(self, name, age):
print('__init__')
self.name = name
self.age = age
# 將對象轉換爲字符串時調用,類似於java中的toString()
def __str__(self):
return 'Person [name=%s, age=%d]' % (self.name, self.age)
# 在對象使用len()函數時調用
def __len__(self):
return len(self.name)
# 在對象使用repr()函數時調用
def __repr__(self):
return 'hello person'
# 將對象轉換爲bool類型時調用
def __bool__(self):
return self.age > 18
# 在對象進行大於比較時調用
def __gt__(self, other): # self表示當前對象,other表示要比較的對象
return self.age > other.age
p1 = Person('唐伯虎', 20)
p2 = Person('秋香', 18)
print(p1)
print(len(p1))
print(repr(p1))
print(bool(p1))
if p1:
print(p1.name, '已成年')
else:
print(p1.name, '未成年')
print(p1 > p2)
六、模塊
1. 簡介
模塊化是指將一個程序分解爲一個個的模塊module,通過組合模塊來搭建出一個完整的程序
優點:便於團隊開發、方便維護、代碼複用
在Python中一個.py文件就是一個模塊,創建模塊實際上就是創建一個.py文件,可以被其他模塊導入並使用
注意:
- 自定義模塊時要注意命名規範,使用小寫,不要使用中文、特殊字符等
- 不要與內置模塊衝突
2. 使用模塊
導入模塊的兩種方式:
-
方式1:import 包名.模塊名 [ as 別名]
-
方式2:from 包名 import 模塊名
from 包名.模塊名 import 變量|函數|類
導入模塊的代碼可以放在任意位置,但一般都放在程序的開頭
# 方式1
# import py04_模塊.mymodule
# print(py04_模塊.mymodule.a) # 調用模塊中的變量
# print(py04_模塊.mymodule.plus(3, 5))
# import py04_模塊.mymodule as m
# print(m.plus(3, 5))
# 方式2
# from py04_模塊 import mymodule
# print(mymodule.b)
# print(mymodule.minus(8, 2))
from py04_模塊.mymodule import b, plus, Calculator
# from py04_模塊.mymodule import * # 不建議
# print(b)
# print(plus(2, 5))
# print(Calculator.sum(3, 12, 5))
'''
__name__屬性是模塊的內置屬性,每個模塊中都有該屬性
當該.py文件是主執行文件,直接被執行時,其值爲__main__
當該.py文件是被調用,導入執行時,其值爲模塊名
'''
# print(__name__)
# 程序入門,類似於Java中的main()方法,只在當直接調用該文件時纔會執行,用來執行測試
if __name__ == '__main__':
print(Calculator.sum(1, 2, 3))
3. Python標準庫
Python提供了一個強大的標準庫,內置了許多非常有用的模塊,可以直接使用(標準庫是隨Python一起安裝)
常用的內置模塊:
- sys:獲取Python解析的信息
- os:對操作系統進行訪問,主要是對目錄或文件進行操作
- math:數學運算
- random:生成隨機數
- datetime:處理日期和時間,提供了多個類
- time:處理時間
import sys
import os
import math
import random
from datetime import datetime, timedelta
import time
print(sys.version) # Python版本
print(sys.platform) # 系統平臺
print(sys.argv) # 命令行參數
print(sys.path) # 模塊搜索路徑,包含了Python解析器查找模塊的搜索路徑
print(sys.modules) # 顯示當前程序中引入的所有模塊
print(sys.getdefaultencoding()) # 默認字符集
# sys.exit('程序退出') # 退出解析器
print('---------------------------------')
print(os.name) # 操作系統的類型
print(os.environ['path']) # 系統的環境變量
print(os.getcwd()) # 當前的目錄
print(os.listdir('d:/')) # 列出指定目錄中的內容
# os.system('ping www.baidu.com') # 執行系統命令
print(os.path.exists('d:/soft')) # 判斷路徑是否存在
print('---------------------------------')
print(math.pi)
print(math.ceil(3.4))
print(math.floor(3.4))
print(math.pow(2, 3))
print(math.trunc(2.6)) # 截尾取整
print(round(2.6))
print(round(3.1415925, 3)) # 四捨五入,保留三位小數
print('---------------------------------')
print(random.random()) # 返回[0,1)之間的隨機浮點數
print(random.randint(1, 101)) # 返回[1,100]之間的隨機整數
print(random.sample([1, 21, 54, 23, 6, 2], 2)) # 從數組中返回隨機兩個元素
print('---------------------------------')
print(datetime.now(), type(datetime.now())) # 返回當前時間
print(datetime.strftime(datetime.now(), '%Y-%m-%d %H:%M:%S')) # 將datetime轉換爲指定格式的str
print(datetime.strftime(datetime.now(), '%Y{0}%m{1}%d{2} %H:%M:%S').format('年', '月', '日'))
print(datetime.strptime('2018-2-14', '%Y-%m-%d')) # 將str轉換爲datetime
print('明天:', datetime.now() + timedelta(days=1)) # timedelta表示兩個時間之間的時間差,可以用來進行日間的加減操作
print('前一秒:', datetime.now() - timedelta(seconds=1))
print('---------------------------------')
print(time.time()) # 返回當前時間的時間戳
print(int(time.time())) # 秒級時間戳
print(int(time.time() * 1000)) # 毫秒時間戳
time.sleep(5) # 休眠5秒
print(1111)
4. 第三方模塊
Python社區提供了大量的第三方模塊,使用方式與標準庫類似
安裝第三方模塊:
-
使用包管理工具pip(隨Python一起安裝的)
pip install 模塊名
-
使用PyCharm來安裝
Settings——>Project——>Project Interpreter
報錯:
AttributeError: module 'pip' has no attribute 'main'
解決:找到PyCharm安裝目錄下的helpers/packaging_tool.py文件,替換其中的do_install和do_uninstall函數
注:官方倉庫比較慢,可以使用豆瓣提供的鏡像倉庫 https://pypi.douban.com/simple/
pyecharts是一個用於Echarts圖表的類庫,便於在Python中根據數據生成可視化的圖表
Echarts是百度開源的一個數據可視化JS庫,主要用來進行數據可視化。
參考:http://pyecharts.org
安裝pyecharts庫
新版本的pyecharts默認不帶地圖文件,如果需要使用地圖,需要自行安裝地圖文件包
七、異常處理和IO操作
1. 異常處理
語法:
try:
可能出現異常的代碼
except:
出現異常後要執行的操作
else:
不出現異常時執行的操作
finally:
無論是否出現異常都必須要執行的操作
try:
print('try...')
a = 5 / int('abc')
# except: # 捕獲所有異常
# except ZeroDivisionError as e: # 捕獲ZeroDivisionError異常,獲取到異常對象
except (ZeroDivisionError, ValueError, Exception) as e: # 捕獲多種異常
print('出現異常啦', e)
else:
print('沒有異常時執行')
finally:
print('finally...')
# 自定義異常,繼承自Exception(Exception類是所有異常類的父類)
class UsernameExistsException(Exception):
pass
def fn(username):
if username == 'admin' or username == 'tom':
raise UsernameExistsException('用戶名已存在') # 使用raise拋出異常
else:
print('ok')
fn(input('請輸入用戶名:'))
2. IO操作
文件操作
'''
讀寫模式:
r 讀模式
w 寫模式(覆蓋)
a 追加模式
r+ 讀寫模式
b 二進制模式
'''
# ----讀取文件
try:
f = open('itany.txt', mode='r', encoding='utf-8') # 打開一個文件,返回一個對象,這個對象就代表着當前打開的文件
print(f.read()) # 一次性讀取所有內容
except FileNotFoundError as e:
print('文件找不到:', e)
finally:
if f:
f.close() # 文件操作後一定要關閉
print('-' * 80)
# 簡寫,使用with...as語句,會自動調用close()
with open('itany.txt', mode='r', encoding='utf-8') as f:
# print(f.read())
# print(f.read(3)) # 每次讀取3個字符
# print(f.read(3))
# print(f.readline().strip()) # 每次讀取一行
# print(f.readline())
lines = f.readlines() # 一次性讀取所有行,返回list
# print(lines)
for line in lines:
print(line.strip())
print('-' * 80)
# ----寫文件
with open('itany.txt', mode='a', encoding='utf-8') as f:
f.write('xxx\n')
f.write('yyy')
print('-' * 80)
# ----讀寫二進制文件
with open('baidu.png', mode='rb') as f:
with open('itany.png', mode='wb') as out:
out.write(f.read())
print('拷貝成功')
文件操作模塊
import os
import shutil
# ----操作文件和目錄
print(os.path.exists('itany.txt')) # 判斷是否存在
print(os.path.abspath('itany.txt')) # 文件的絕對路徑
print(os.path.isfile('itany.txt')) # 判斷是否爲文件
print(os.path.isdir('itany.txt')) # 判斷是否爲目錄
print(os.listdir('.')) # 列出指定目錄下所有內容
# 找出當前目錄下所有的文件夾
dirs = [f for f in os.listdir('.') if os.path.isdir(f)]
print(dirs)
# 創建/刪除目錄
# os.mkdir('world')
if os.path.exists('world'):
os.rmdir('world')
# 重命名文件或目錄
# os.rename('itany.txt', 'aaa.txt')
# 刪除文件
# os.remove('aaa.txt')
# 拷貝文件
shutil.copy('baidu.png', 'bbb.png')
八、訪問MySQL
1. 簡介
使用pymysql模塊:pip install pymysql
2. 基本操作
增刪改
import pymysql
# 定義數據庫連接信息
config = {
'host': 'localhost',
'port': 3306,
'user': 'root',
'password': '',
'database': 'python',
'charset': 'utf8'
}
# 獲取連接
conn = pymysql.connect(**config)
# 獲取遊標,相當於java中的Statement
cursor = conn.cursor()
# 執行sql
sql = '''
insert into t_user
(username,password,age,height)
values
(%s,%s,%s,%s)
'''
num = cursor.execute(sql, ['alice', '123', 18, 175.2]) # 爲佔位符%s賦值
print(num)
# 提交事務
conn.commit()
# 關閉資源
cursor.close()
conn.close()
查詢
# 獲取遊標,相當於java中的Statement
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # 可以指定cursor的類型爲字典,查詢結果爲Dict類型
# 執行sql
sql = '''
select
id,username,password,age,height
from t_user
'''
cursor.execute(sql)
# 獲取查詢結果
# print(cursor.fetchone()) # 每次讀取一條,返回的是元組
# print(cursor.fetchone())
# print(cursor.fetchmany(2)) # 獲取多條
# print(cursor.fetchall()) # 獲取所有
for u in cursor.fetchall():
print(u['username'], u['age'])