Python 各進(jìn)制的表示與轉(zhuǎn)換
Python 用 ob
表示二進(jìn)制
二進(jìn)制轉(zhuǎn)十進(jìn)制
>>> 0b10
2
>>> 0b11
3
用 0o
表示八進(jìn)制
八進(jìn)制轉(zhuǎn)十進(jìn)制
>>> 0o10
8
>>> 0o11
9
用 0x
表示十六進(jìn)制
十六進(jìn)制轉(zhuǎn)十進(jìn)制
>>> 0x10
16
>>> 0x1F
31
其他進(jìn)制轉(zhuǎn)二進(jìn)制使用 bin()
函數(shù)
>>> bin(10)
'0b1010'
>>> bin(0o7)
'0b111'
>>> bin(0xE)
'0b1110'
其他進(jìn)制轉(zhuǎn)十進(jìn)制使用 int()
函數(shù)
>>> int(0b111)
7
>>> int(0o77)
63
>>> int(0xE)
14
其他進(jìn)制轉(zhuǎn)十六進(jìn)制使用 hex
函數(shù)
>>> hex(888)
'0x378'
>>> hex(0o7777)
'0xfff'
>>> hex(0b111)
'0x7'
其他進(jìn)制轉(zhuǎn)八進(jìn)制使用 oct()
函數(shù)
>>> oct(0b111)
'0o7'
>>> oct(888)
'0o1570'
>>> oct(0x777)
'0o3567'
基本數(shù)據(jù)類型
- number
- int
- float
- bool
- Ture
- Flase
- 序列 有序九串,可以索引取值绞佩,切片寺鸥,常用操作:
+
,*
品山,in
胆建,not in
,len
肘交,max
笆载,min
- str 不可變
- list 可變
- tuple 不可變
- Set 集合 無(wú)序,可變涯呻,可以
-
求差集凉驻,&
求交集,|
求并集 - Dict 字典复罐,無(wú)序涝登,可變
number
>>> type(1*1)
<class 'int'>
>>> type(1*1.0)
<class 'float'>
>>> type(2/2)
<class 'float'>
>>> type(2//2)
<class 'int'>
>>> type(True)
<class 'bool'>
>>> type(False)
<class 'bool'>
>>> int(True)
1
>>> int(False)
0
>>> bool(1)
True
>>> bool(0)
False
>>> bool('abc')
True
>>> bool('')
False
>>> bool([1,2,3])
True
>>> bool([])
False
>>> bool(None)
False
字符串 str
原始字符串
在字符串前面加 r
表示原始字符串,即所見即所得
>>> print(r'hello /n world')
hello /n world
字符串運(yùn)算
字符串拼接
>>> 'hello' + 'world'
'helloworld'
>>>
>>> 'hello' * 3
'hellohellohello'
索引
>>> 'hello world'[0]
'h'
>>> 'hello world'[1]
'e'
>>> 'hello world'[4]
'o'
>>> 'hello world'[-1]
'd'
>>> 'hello world'[-3]
'r'
切片
>>> 'hello world'[0:4]
'hell'
>>> 'hello world'[0:5]
'hello'
>>> 'hello world'[0:-1]
'hello worl'
>>> 'hello world'[6:10]
'worl'
>>> 'hello world'[6:11]
'world'
>>> 'hello world'[6:-1]
'worl'
>>> 'hello world'[6:]
'world'
>>> 'hello world'[-5:]
'world'
列表 list
定義列表
>>> ['hello', 1,2,3, True]
['hello', 1, 2, 3, True]
嵌套列表
>>> [['hello', 'world'], [1, 2], [True, False]]
[['hello', 'world'], [1, 2], [True, False]]
列表的基本操作
索引
>>> [1, 2, 3, 4][0]
1
>>> [1, 2, 3, 4][2]
3
切片效诅,返回的是列表
>>> [1, 2, 3, 4][0:2]
[1, 2]
>>> [1, 2, 3, 4][-1:]
[4]
拼接
>>> [1, 2, 3, 4] + ['a', 'b']
[1, 2, 3, 4, 'a', 'b']
>>> [1, 2, 3, 4, 'a', 'b'] * 2
[1, 2, 3, 4, 'a', 'b', 1, 2, 3, 4, 'a', 'b']
元組 tuple
定義元祖
>>> (-1, 'hello', True)
(-1, 'hello', True)
元祖的基本操作
>>> (1, 2, 3)[0]
1
>>> (1, 2, 3)[-2:]
(2, 3)
>>> (1, 2) + ('a', 'b')
(1, 2, 'a', 'b')
>>> (1, 'a') * 2
(1, 'a', 1, 'a')
當(dāng) ()
中只有一個(gè)元素的時(shí)候胀滚,python 會(huì)默認(rèn)把 ()
當(dāng)做運(yùn)算符,像是:(1 + 1) * 2
中的 ()
>>> type((1, 2, 3))
<class 'tuple'>
>>> type((1))
<class 'int'>
>>> type(('hello'))
<class 'str'>
如果想要定義只有一個(gè)元素的元組填帽,可以在元素后面加一個(gè)英文逗號(hào)
>>> type((1,))
<class 'tuple'>
定義空元組
>>> type(())
<class 'tuple'>
已經(jīng)有了列表蛛淋,為什么需要元組?
為了代碼穩(wěn)定性篡腌。不可改變的元組類型有它的優(yōu)勢(shì),因?yàn)楫?dāng)嘗試修改元組的時(shí)候勾效,會(huì)報(bào)錯(cuò)嘹悼,避免錯(cuò)誤隱藏在代碼中。所以层宫,列表和元組杨伙,優(yōu)先選擇使用元組,前提是存儲(chǔ)的數(shù)據(jù)是靜態(tài)的萌腿,不需要改變限匣,如果存儲(chǔ)的數(shù)據(jù)是動(dòng)態(tài)的,需要改變毁菱,那么還是要用列表米死。
集合 set
定義集合
>>> {1, 2, 3, 'hello'}
{1, 2, 3, 'hello'}
序列有序,集合無(wú)序贮庞,所以集合無(wú)法索引取值
>>> {1, 2, 3}[0]
<stdin>:1: SyntaxWarning: 'set' object is not subscriptable; perhaps you missed a comma?
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'set' object is not subscriptable
序列有序峦筒,集合無(wú)序,所以集合無(wú)法切片
>>> {1, 2, 3}[-2:]
<stdin>:1: SyntaxWarning: 'set' object is not subscriptable; perhaps you missed a comma?
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'set' object is not subscriptable
集合的元素不能重復(fù)
>>> {1, 1, 2, 2, 3, 3}
{1, 2, 3}
集合的基本操作
>>> len({1, 2, 3})
3
>>> 2 in {1, 2, 3}
True
>>> 2 not in {1, 2, 3}
False
>>> {1, 2, 3, 4, 5, 6} - {3, 4}
{1, 2, 5, 6}
>>> {1, 2, 3, 4, 5, 6} & {3, 4, 7}
{3, 4}
>>> {1, 2, 3, 4, 5, 6} | {3, 4, 7}
{1, 2, 3, 4, 5, 6, 7}
定義一個(gè)空集合
>>> type({})
<class 'dict'>
>>> type(set())
<class 'set'>
字典 dict
定義字典
>>> {1:'a', 2:'b', 3:'c'}
{1: 'a', 2: 'b', 3: 'c'}
Key 不能重復(fù)
>>> {1:'a', 1:'b', 3:'c'}
{1: 'b', 3: 'c'}
Key 不可變
>>> {[1,2]:'a', 1:'b', 3:'c'}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> {(1,2):'a', 1:'b', 3:'c'}
{(1, 2): 'a', 1: 'b', 3: 'c'}
變量與運(yùn)算符
值類型和引用類型
>>> a = 1
>>> b = a
>>> a = 3
>>> print(a)
3
>>> print(b)
1
>>> a = [1, 2, 3]
>>> b = a
>>> a[0] = 'x'
>>> print(a)
['x', 2, 3]
>>> print(b)
['x', 2, 3]
int
屬于值類型窗慎,不可變物喷;list
屬于引用類型卤材,可變。由于 int
不可改變峦失,所以當(dāng) a = 3
給 a
進(jìn)行重新賦值的時(shí)候扇丛,a
指向了一個(gè)新的值;當(dāng) a[0] = ['x']
修改了原來(lái)的值尉辑,a
不需要指向一個(gè)新的值晕拆,因?yàn)?list
是可變的。
值類型包括:int
str
tuple
引用類型包括:list
set
dict
不可變的字符串:
>>> a = 'hello'
>>> a[0]
'h'
>>> a[0] = 'x'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
可變的列表:
>>> a = [1, 2, 3]
>>> id(a)
140608652166656
>>> a[0] = 'x'
>>> print(a)
['x', 2, 3]
>>> id(a)
140608652166656
不可變的元組
>>> a = (1, 2, 3)
>>> a[0]
1
>>> a[0] = 'x'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
列表和元組
>>> l = [1, 2, 3]
>>> l.append(4)
>>> print(l)
[1, 2, 3, 4]
>>> t = (1, 2, 3)
>>> t.append(4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'append'
元組適合存儲(chǔ)一組不變的數(shù)據(jù)材蹬;列表適合存儲(chǔ)一組動(dòng)態(tài)的數(shù)據(jù)实幕。
元組中嵌套的列表是可以改變的
>>> t = (1, 2, [1, 2, 3])
>>> t[2][0] = 'x'
>>> print(t)
(1, 2, ['x', 2, 3])
運(yùn)算符號(hào)
算數(shù)運(yùn)算符:+
-
*
/
//
%
**
賦值運(yùn)算符:=
+=
-=
*=
/=
%=
**=
//=
比較(關(guān)系)運(yùn)算符:==
!=
>
<
>=
<=
邏輯運(yùn)算符:and
or
not
成員運(yùn)算符:in
not in
身份運(yùn)算符:is
is not
位運(yùn)算符:&
|
~
<<
>>
>>> a = 1
>>> a += a >= 1 # 相當(dāng)于 a += True 所以等于是計(jì)算 a += 1
>>> print(a)
2
int
和 float
類型,非 0 時(shí)被 python 認(rèn)為是 True
str
list
tuple
set
dict
類型堤器,為空時(shí)被 python 認(rèn)為是 False
>>> 1 and 1
1
>>> [1] or []
[1]
>>> not 1
False
根據(jù)兩個(gè)元素判斷真假昆庇,第一個(gè)元素能判斷出來(lái)就直接返回第一個(gè)元素,第一個(gè)元素判斷不出來(lái)就返回第二個(gè)元素
>>> 1 and 0 # 都為真結(jié)果才為真闸溃,1 為真整吆,判斷不出結(jié)果,0 為假辉川,結(jié)果為假表蝙,返回 0
0
>>> 0 and 1 # 0 為假,可以判斷結(jié)果為假乓旗,不需要判斷第二個(gè)元素府蛇,直接返回 0
0
>>> 1 and 2
2
>>> 2 and 1
1
>>> 1 or 0 # 有一個(gè)為真,結(jié)果就為真屿愚,1 為真直接返回 1
1
>>> 0 or 1 # 0 為假汇跨,判斷不出結(jié)果,再判斷 1妆距,1 為真穷遂,結(jié)果為真,返回 1
1
字典根據(jù) key
判斷 in
或者 not in
>>> 'a' in {'a': 1}
True
==
判斷值是否相等娱据,is
判斷內(nèi)存地址 id
是否相等
>>> a = 1
>>> b = 1.0
>>> id(a)
140519935187248
>>> id(b)
140519935914512
>>> a == b
True
>>> a is b
False
集合無(wú)序蚪黑,元組有序
>>> s1 = {1, 2, 3}
>>> s2 = {3, 2, 1}
>>> s1 == s2
True
>>> s1 is s2
False
>>> t1 = (1, 2, 3)
>>> t2 = (3, 2, 1)
>>> t1 == t2
False
>>> t1 is t2
False
判斷變量的類型
>>> a = 'hello'
>>> isinstance(a, str)
True
>>> isinstance(a, int)
False
>>> isinstance(a, (str, int, float))
True
>>> isinstance(a, (int, float))
False
對(duì)象的三個(gè)特征:value
id
type
,判斷三個(gè)特征:==
is
isinstance
條件與循環(huán)
條件
account = 'answer'
password = '123456'
print('please input account:')
user_account = input()
print('please input password:')
user_password = input()
if account == user_account and password == user_password:
print('success')
else:
print('fail')
a = input()
a = int(a)
if a == 1:
print('apple')
elif a == 2:
print('orange')
elif a == 3:
print('banana')
else:
print('shopping')
循環(huán)
counter = 0
while counter <= 10:
counter += 1
print(counter)
else:
print('EOF')
a = [['apple', 'orange', 'banana'], (1, 2, 3)]
for x in a:
for y in x:
print(y)
else:
print('fruit is gone')
退出所有循環(huán)
a = [1, 2, 3]
for x in a:
if x == 2:
break
print(x)
1
退出本次循環(huán)
a = [1, 2, 3]
for x in a:
if x == 2:
continue
print(x)
1
3
# 實(shí)現(xiàn) 1中剩,3荒典,5霎烙,7
a = [1, 2, 3, 4, 5, 6, 7, 8]
# 循環(huán)實(shí)現(xiàn)
for i in range(0, len(a), 2):
print(a[i], end='|')
# 切片實(shí)現(xiàn)
b = a[0: len(a): 2]
print(b)
包、模塊、函數(shù)與變量作用域
python 的組織結(jié)構(gòu):包->模塊(.py文件)->類
當(dāng)一個(gè)包被導(dǎo)入的時(shí)候览绿,包中的 __init__.py
文件會(huì)自動(dòng)執(zhí)行
當(dāng)導(dǎo)入一個(gè)模塊的時(shí)候卢肃,就會(huì)執(zhí)行這個(gè)模塊的代碼
c1.py
a = 2
print(a)
c2.py
import c1
執(zhí)行 c2.py
python c2.py
執(zhí)行結(jié)果
2
dir()
函數(shù)返回當(dāng)前模塊的所有變量幻锁,包括以雙下劃線 __
開頭結(jié)尾的模塊內(nèi)置變量和我們自己定義的變量
模塊內(nèi)置變量:
__package__
返回包名,如果是入口文件沸伏,返回NoneType
因?yàn)槿肟谖募粚儆谌魏伟?/p>__name__
返回包名.模塊名
,如果是入口文件动分,返回__main__
__file__
返回模塊在系統(tǒng)中的完整路徑毅糟,如果是入口文件,返回模塊名執(zhí)行文件時(shí)的路徑澜公,比如執(zhí)行python t/c2.py
姆另,那么返回t/c2.py
__doc__
返回模塊的文檔注釋
dir()
函數(shù)傳入?yún)?shù),返回指定模塊的變量坟乾,比如 dir(sys)
-m
把入口文件當(dāng)做模塊執(zhí)行迹辐,比如:python -m t.c2
相對(duì)導(dǎo)入和絕對(duì)導(dǎo)入
入口文件中不能使用相對(duì)導(dǎo)入,除非把入口文件當(dāng)做模塊執(zhí)行
函數(shù)
認(rèn)識(shí)函數(shù)
# 使用內(nèi)置函數(shù) round 保留小數(shù)點(diǎn)后兩位
a = 3.14159
result = round(a, 2)
print(result)
函數(shù)的特點(diǎn)
- 功能性
- 隱藏細(xì)節(jié)
- 避免編寫重復(fù)的代碼
函數(shù)的定義及運(yùn)行特點(diǎn)
def funcname(parameter_list):
pass
- 參數(shù)列表可以沒有
- return 返回結(jié)果甚侣,沒有 return 則返回 None
def add(x, y):
result = x + y
return result
def print_code(code):
print(code)
a = add(1, 2)
b = print_code('python')
print(a, b)
執(zhí)行結(jié)果
python
(3, None)
如何讓函數(shù)返回多個(gè)結(jié)果
def damage(skill1, skill2):
damage1 = skill1 * 2
damage2 = skill2 * 3 + 1
# 將返回一個(gè)元組
return damage1, damage2
# 使用有意義的變量名接收返回結(jié)果
skill1_damage, skill2_damage = damage(3, 2)
print(skill1_damage, skill2_damage)
序列解包
d = 1,2,3
# d 的類型是元組
print(type(d))
# 序列解包
a,b,c = d
關(guān)鍵字參數(shù)
def damage(skill1, skill2):
damage1 = skill1 * 2
damage2 = skill2 * 3 + 1
return damage1, damage2
# 調(diào)用函數(shù)的時(shí)候明吩,實(shí)參使用關(guān)鍵字參數(shù),代碼更易讀
skill1_damage, skill2_damage = damage(skill1=3, skill2=2)
可變參數(shù)
任意個(gè)數(shù)的參數(shù)
def demo(*param):
print(type(param))
print(param)
demo(1,2,3)
執(zhí)行結(jié)果
<type 'tuple'>
(1, 2, 3)
使用可變參數(shù)
def sum(*param):
sum = 0
for i in param:
sum += i
print(sum)
sum(1,2,3)
執(zhí)行結(jié)果
6
關(guān)鍵字可變參數(shù)
任意個(gè)數(shù)的關(guān)鍵字參數(shù)
def city_temp(**param):
print(type(param))
print(param)
city_temp(bj='32c', sh='36c', gz='38c')
執(zhí)行結(jié)果
<type 'dict'>
{'sh': '36c', 'gz': '38c', 'bj': '32c'}
使用
def city_temp(**param):
for key,value in param.items():
print(key, ':', value)
d = {'bj':'32c', 'sh':'36c', 'gz':'38c'}
# 如果實(shí)參是字典殷费,加兩個(gè)**
city_temp(**d)
變量作用域
每一個(gè)變量印荔,都有它的作用范圍
c = 10
def add(x, y):
c = x + y
print(c)
add(1, 2)
print(c)
執(zhí)行結(jié)果
3
10
再看一個(gè)例子,在函數(shù)內(nèi)部定義一個(gè)變量详羡,然后在函數(shù)外部打印這個(gè)變量
def demo():
a = 1
print(a)
在函數(shù)外部打印變量 a 仍律,執(zhí)行結(jié)果,報(bào)錯(cuò)
NameError: name 'a' is not defined
如果先定義一個(gè)變量实柠,然后在函數(shù)內(nèi)部引用變量水泉,再執(zhí)行函數(shù)是可以的
a = 1
def demo():
print(a)
demo()
執(zhí)行結(jié)果
1
在函數(shù)外部定義的變量,被稱為全局變量主到;在函數(shù)內(nèi)部定義的變量茶行,被稱為局部變量。
然后看一下登钥,在循環(huán)外部,是可以引用循環(huán)內(nèi)部定義的變量的
def demo():
for i in range(0,3):
a = 1
print(a)
demo()
執(zhí)行結(jié)果
1
作用域鏈
引用變量時(shí)娶靡,由內(nèi)到外逐級(jí)尋找
a = 1
def func1():
a = 2
def func2():
a = 3
print(a)
func2()
func1()
執(zhí)行結(jié)果
3
注釋掉 a = 3
a = 1
def func1():
a = 2
def func2():
# a = 3
print(a)
func2()
func1()
執(zhí)行結(jié)果
2
再注釋掉 a = 2
a = 1
def func1():
# a = 2
def func2():
# a = 3
print(a)
func2()
func1()
執(zhí)行結(jié)果
1
global 關(guān)鍵字
把局部變量變成全局變量
def demo():
global a
a = 1
demo()
print(a)
執(zhí)行結(jié)果
1
全局變量不會(huì)局限在當(dāng)前模塊牧牢,比如此時(shí)的變量 a ,是全局變量姿锭,那么在其他模塊也是可以引用的塔鳍。
面向?qū)ο?/h2>
類的定義
變量名小寫,單詞之間使用下劃線間隔
類名首字母大寫呻此,單詞之間使用大寫字母間隔轮纫,而不是使用下劃線間隔
類下面的函數(shù),必須有 self
參數(shù)
在函數(shù)中引用類下面的全局變量的時(shí)候焚鲜,也必須加 self.
參數(shù)
class Student():
name = '張三'
age = 18
def print_file(self):
print('name: ' + self.name)
print('age: ' + str(self.age))
使用類之前掌唾,需要先對(duì)類進(jìn)行實(shí)例化
student = Student()
調(diào)用類下面的函數(shù)
student.print_file()
執(zhí)行結(jié)果
name: 張三
age: 18
類最基本的作用放前,就是像上面這樣,把變量和函數(shù)封裝起來(lái)
一個(gè)模塊下面可以定義多個(gè)類
定義類的模塊下面只定義類糯彬,類的實(shí)例化和使用放在其他模塊下面
函數(shù)與方法的區(qū)別
直接定義在模塊下面的函數(shù)凭语,稱為函數(shù);定義在類下面的函數(shù)撩扒,稱為方法
直接定義在模塊下面的變量似扔,稱為變量,定義在類下面的變量搓谆,稱為數(shù)據(jù)成員
不必糾結(jié)函數(shù)/方法的叫法炒辉。
類與對(duì)象
類是現(xiàn)實(shí)世界或思維世界中的實(shí)體在計(jì)算機(jī)中的反映。它將數(shù)據(jù)(變量)以及對(duì)這些數(shù)據(jù)的操作(方法)封裝在一起泉手。
變量(數(shù)據(jù)成員)是類或?qū)ο蟮奶卣髑埽椒ㄊ穷惢驅(qū)ο蟮男袨椤?/p>
類像模板,通過(guò)這個(gè)模板可以產(chǎn)生很多個(gè)不同的對(duì)象螃诅。
構(gòu)造函數(shù)
類在實(shí)例化的時(shí)候啡氢,會(huì)自動(dòng)調(diào)用構(gòu)造函數(shù) __init__()
構(gòu)造函數(shù)除了在類實(shí)例化的時(shí)候,自動(dòng)調(diào)用术裸,也可以顯示的調(diào)用倘是,但很少這樣做。
函數(shù)在沒有做 return
的時(shí)候袭艺,會(huì)默認(rèn)返回 None
搀崭,構(gòu)造函數(shù)也一樣。
構(gòu)造函數(shù)可以顯示的 return None
猾编,但是不能 return
其他內(nèi)容瘤睹。
類變量與實(shí)例變量
類變量是和類相關(guān)的變量;實(shí)例變量是和對(duì)象相關(guān)的變量答倡。
局部變量不會(huì)覆蓋全局變量轰传;實(shí)例變量不會(huì)覆蓋類變量。
通過(guò)構(gòu)造函數(shù)創(chuàng)建類這個(gè)模板的不同對(duì)象(實(shí)例化)
class Student():
# 類變量
name = '張三'
age = 18
# 構(gòu)造函數(shù)瘪撇,初始化對(duì)象的屬性
def __init__(self, name, age):
# 實(shí)例變量
self.name = name
self.age = age
def do_homework(self):
print('homework')
# 實(shí)例化
student1 = Student('小明', 18)
student2 = Student('李雷', 20)
# 實(shí)例變量
print(student1.name)
print(student2.name)
# 類變量
print(Student.name)
執(zhí)行結(jié)果
小明
李雷
張三
類變量定義 name 和 age 其實(shí)不合適获茬,因?yàn)轭愂浅橄蟮模荒苷f(shuō)學(xué)生們的名字和年齡是什么倔既,應(yīng)該定義為實(shí)例變量恕曲,因?yàn)閷?shí)例是具體的,可以說(shuō)某個(gè)學(xué)生的姓名和年齡是什么渤涌。那類變量怎么用呢佩谣?
比如,可以創(chuàng)建一個(gè)類變量实蓬,用來(lái)計(jì)算一個(gè)班級(jí)的學(xué)生總?cè)藬?shù)
class Student():
# 類變量茸俭,一個(gè)班級(jí)的學(xué)生總數(shù)
sum = 0
# 構(gòu)造函數(shù)吊履,初始化對(duì)象的屬性
def __init__(self, name, age):
# 實(shí)例變量
self.name = name
self.age = age
類與對(duì)象的變量查找順序
當(dāng)訪問(wèn)一個(gè)實(shí)例變量的時(shí)候(student1.name
),首先會(huì)在實(shí)例的所有變量中查找(student1.__dict__
)瓣履,如果沒有找到率翅,會(huì)在類變量里面查找(Student.__dict__
),如果還沒有的話袖迎,會(huì)到父類中查找冕臭。
self 與實(shí)例方法
實(shí)例方法:與實(shí)例相關(guān)的方法,第一個(gè)參數(shù)是 self
class Student():
sum = 0
# 構(gòu)造函數(shù)
def __init__(self, name, age):
self.name = name
self.age = age
# 實(shí)例方法
def do_homework(self):
print('homework')
self
就是當(dāng)前對(duì)象燕锥,比如對(duì)象 student1
調(diào)用 do_homework()
方法(student1.do_homework()
)辜贵,那么這時(shí)候 do_homework(self)
方法中的 self
參數(shù),就是指的對(duì)象 student1
構(gòu)造函數(shù)屬于特殊的實(shí)例方法归形,與普通的實(shí)例方法有所不同:
- 首先托慨,調(diào)用方式不同
- 調(diào)用構(gòu)造函數(shù):
Student('小明', 18)
- 調(diào)用普通實(shí)例方法:
student1.do_homework()
- 調(diào)用構(gòu)造函數(shù):
- 其次,作用不同
- 構(gòu)造函數(shù)用來(lái)初始化對(duì)象的屬性
- 普通實(shí)例方法用來(lái)定義對(duì)象的行為
在實(shí)例方法中訪問(wèn)實(shí)例變量與類變量
在實(shí)例方法中訪問(wèn)實(shí)例變量和類變量
class Student():
# 類變量
sum = 0
# 構(gòu)造函數(shù)
def __init__(self, name, age):
# 實(shí)例變量
self.name = name
self.age = age
# 在實(shí)例方法中訪問(wèn)實(shí)例變量
print(self.name)
# 在實(shí)例方法中訪問(wèn)類變量的第一種方式
print(Student.sum)
# 在實(shí)例方法中訪問(wèn)類變量的第二種方式
print(self.__class__.sum)
實(shí)例化類暇榴,自動(dòng)調(diào)用構(gòu)造函數(shù)
student1 = Student('小明', 18)
執(zhí)行結(jié)果
小明
0
0
在實(shí)例方法中厚棵,修改類變量
class Student():
# 類變量
sum = 0
# 構(gòu)造函數(shù)
def __init__(self, name, age):
# 實(shí)例變量
self.name = name
self.age = age
# 修改類變量
Student.sum += 1
print('當(dāng)前班級(jí)學(xué)生總數(shù)是:' + str(Student.sum))
每實(shí)例化一次,就自動(dòng)調(diào)用一次構(gòu)造函數(shù)
student1 = Student('小明', 18)
student2 = Student('李雷', 20)
student3 = Student('小紅', 17)
執(zhí)行結(jié)果
當(dāng)前班級(jí)學(xué)生總數(shù)是:1
當(dāng)前班級(jí)學(xué)生總數(shù)是:2
當(dāng)前班級(jí)學(xué)生總數(shù)是:3
類方法
類方法用于操作類相關(guān)的變量
定義類方法
- 在方法上添加
@classmethod
- 第一個(gè)參數(shù)
cls
class Student():
# 類變量
sum = 0
# 構(gòu)造函數(shù)
def __init__(self, name, age):
# 實(shí)例變量
self.name = name
self.age = age
# 實(shí)例方法
def do_homework(self):
print('homework')
# 類方法
@classmethod
def plus_sum(cls):
cls.sum += 1
print('當(dāng)前班級(jí)學(xué)生總數(shù)是:' + str(cls.sum))
每創(chuàng)建一個(gè)對(duì)象之后蔼紧,調(diào)用一次類方法
student1 = Student('小明', 18)
Student.plus_sum()
student2 = Student('李雷', 20)
Student.plus_sum()
student3 = Student('小紅', 17)
Student.plus_sum()
執(zhí)行結(jié)果
當(dāng)前班級(jí)學(xué)生總數(shù)是:1
當(dāng)前班級(jí)學(xué)生總數(shù)是:2
當(dāng)前班級(jí)學(xué)生總數(shù)是:3
對(duì)象也可以調(diào)用類方法婆硬,但是不建議這么用
cls
就是當(dāng)前類。Student.plus_sum()
時(shí)奸例,plus_sum(cls)
中的 cls
就指的是類 Student
類方法不能訪問(wèn)實(shí)例變量
靜態(tài)方法
靜態(tài)方法需要在方法名上添加 @staticmethod
靜態(tài)方法沒有 self
或 cls
參數(shù)
靜態(tài)方法可以被對(duì)象彬犯,也可以被類調(diào)用
靜態(tài)方法不能訪問(wèn)實(shí)例變量
靜態(tài)方法,不建議用
成員可見性:公開和私有
成員:指的是變量和方法
變量和方法的調(diào)用查吊,都有內(nèi)部調(diào)用和外部調(diào)用
class Student():
sum = 0
def __init__(self, name, age):
self.name = name
self.age = age
def do_homework(self):
# 內(nèi)部調(diào)用
self.do_english_homework()
print('homework')
def do_english_homework(self):
print('english homework')
student1 = Student('小明', 18)
# 外部調(diào)用
student1.do_english_homework()
有時(shí)候我們不希望變量在外部被修改谐区,比如下面的實(shí)例變量 score
class Student():
sum = 0
def __init__(self, name, age, score):
self.name = name
self.age = age
self.score = score
不希望像這樣在外部被修改
student1 = Student('小明', 18)
student1.score = -2
所以,可以添加一個(gè)方法逻卖,專門用于操作 score
class Student():
sum = 0
def __init__(self, name, age):
self.name = name
self.age = age
# 初始化默認(rèn)為 0
self.score = 0
def marking(self, score):
# 判斷如果傳入的分?jǐn)?shù)小于 0
if score < 0:
# 那么分?jǐn)?shù)等于 0
score = 0
# 如果傳入的分?jǐn)?shù)不小于 0宋列,那么分?jǐn)?shù)就等于傳入的分?jǐn)?shù)
self.score = score
print(self.name + '同學(xué)的考試分?jǐn)?shù)是:' + str(self.score))
student1 = Student('小明', 18)
student1.marking(-1)
student1.marking(59)
結(jié)果
小明同學(xué)的考試分?jǐn)?shù)是:0
小明同學(xué)的考試分?jǐn)?shù)是:59
所有對(duì)類下面的變量進(jìn)行修改的操作,都應(yīng)該由方法來(lái)完成评也。
但是虚茶,現(xiàn)在其實(shí)仍然可以通過(guò) student1.score = -3
在外部直接賦值,因?yàn)?score
的成員可見性是公開的仇参。
在 python 中,如果變量或方法沒有以雙下劃線開頭(只開頭婆殿,不結(jié)尾)诈乒,那么它的可見性就是公開的。
所以可以把 score
變成私有變量
class Student():
sum = 0
def __init__(self, name, age):
self.name = name
self.age = age
# 私有變量
self.__score = 0
def marking(self, score):
# 判斷如果傳入的分?jǐn)?shù)小于 0
if score < 0:
score = 0
# 如果傳入的分?jǐn)?shù)不小于 0
self.__score = score
print(self.name + '同學(xué)的考試分?jǐn)?shù)是:' + str(self.__score))
然后在外部賦值
student1 = Student('小明', 18)
student1.__score = -1
結(jié)果:沒有報(bào)錯(cuò)
查看對(duì)象的成員
print(student1.__dict__)
結(jié)果
{'name': '小明', 'age': 18, '_Student__score': 0, '__score': -1}
結(jié)果中值等于 0 的 _Student__score
是私有變量 __scoore
婆芦,而值等于 -1 的 __score
是在外部賦值的時(shí)候怕磨,給對(duì)象添加了一個(gè)新的變量喂饥。python 會(huì)對(duì)私有變量重新命名,以這種方式達(dá)到私有變量再被外部調(diào)用的時(shí)候不被找到肠鲫,不過(guò)其實(shí)可以通過(guò) _Student__score
來(lái)訪問(wèn)员帮,所以嚴(yán)格的說(shuō),python 沒有私有變量导饲。
繼承
繼承捞高,避免我們定義重復(fù)的變量或重復(fù)的方法。
父類
class Human:
sum = 0
def __init__(self, name, age):
self.name = name
self.age = age
def get_name(self):
print(self.name)
子類繼承父類
class Student(Human):
def __init__(self, name, age):
self.name = name
self.age = age
def do_homework(self):
print('homework')
執(zhí)行
student1 = Student('小明', 18)
print(Student.sum)
print(student1.sum)
print(student1.name)
print(student1.age)
student1.get_name()
結(jié)果
0
0
小明
18
小明
在子類中渣锦,調(diào)用父類的方法
class Student(Human):
def __init__(self, school, name, age):
self.school = school
# 調(diào)用父類的構(gòu)造函數(shù)
Human.__init__(self, name, age)
def do_homework(self):
print('homework')
執(zhí)行
student1 = Student('清華大學(xué)', '小明', 18)
print(student1.school)
print(student1.name)
print(student1.age)
結(jié)果
清華大學(xué)
小明
18
上面這樣在子類的中調(diào)用父類的方法的方式硝岗,雖然可以,但是有問(wèn)題袋毙,Human.__init__(self, name, age)
是在用類型檀,調(diào)用實(shí)例方法
所以,調(diào)用父類的方法需要使用 super()
函數(shù):
super(當(dāng)前類名, self).要調(diào)用的父類當(dāng)中的方法名(參數(shù))
父類
class Human:
sum = 0
def __init__(self, name, age):
self.name = name
self.age = age
def get_name(self):
print(self.name)
def do_homework(self):
print('這是父類中的 do_homework 方法')
子類
class Student(Human):
def __init__(self, school, name, age):
self.school = school
# 調(diào)用父類的構(gòu)造函數(shù)
super(Student, self).__init__(name, age)
def do_homework(self):
# 調(diào)用父類中的 do_homework 方法
super(Student, self).do_homework()
print('這是子類中的 do_homework 方法')
執(zhí)行
student1 = Student('清華大學(xué)', '小明', 18)
student1.do_homework()
結(jié)果
這是父類中的 do_homework 方法
這是子類中的 do_homework 方法