一、Python3 輸入和輸出
輸出格式:
Python兩種輸出值的方式: 表達式語句和 print() 函數。
第三種方式是使用文件對象的 write() 方法,標準輸出文件可以用 sys.stdout 引用。(使用 str.format() 函數來格式化輸出值,將輸出的值轉成字符串,可以使用 repr() 或 str() 函數來實現)
>>> for x in range(1, 11):
... print(repr(x).rjust(2), repr(x*x).rjust(3), end=' ')
... # 注意前一行 'end' 的使用
... print(repr(x*x*x).rjust(4))
...
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000
>>> for x in range(1, 11):
... print('{0:2d} {1:3d} {2:4d}'.format(x, x*x, x*x*x))
...
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000
這個例子展示了字符串對象的 rjust() 方法, 它可以將字符串靠右, 並在左邊填充空格。
str.format() 的基本使用如下:
>>> print('{}網址: "{}!"'.format('教程', 'www.runoob.com'))
教程網址: "www.runoob.com!"
在括號中的數字用於指向傳入對象在 format() 中的位置,如下所示:
>>> print('{0} 和 {1}'.format('Google', 'Runoob'))
Google 和 Runoob
>>> print('{1} 和 {0}'.format('Google', 'Runoob'))
Runoob 和 Google
可選項 : 和格式標識符可以跟着字段名。 這就允許對值進行更好的格式化。 下面的例子將 Pi 保留到小數點後三位:
>>> import math
>>> print('常量 PI 的值近似爲 {0:.3f}。'.format(math.pi))
常量 PI 的值近似爲 3.142。
在 : 後傳入一個整數, 可以保證該域至少有這麼多的寬度。
>>> table = {'Google': 1, 'Runoob': 2, 'Taobao': 3}
>>> for name, number in table.items():
... print('{0:10} ==> {1:10d}'.format(name, number))
...
Google ==> 1
Runoob ==> 2
Taobao ==> 3
讀取鍵盤輸入
Python提供了 input() 內置函數從標準輸入讀入一行文本,默認的標準輸入是鍵盤。input 可以接收一個Python表達式作爲輸入,並將運算結果返回。
#!/usr/bin/python3
str = input("請輸入:");
print ("你輸入的內容是: ", str)
讀和寫文件
open() 將會返回一個 file 對象,基本語法格式如下:
open(filename, mode)
- filename:包含了你要訪問的文件名稱的字符串值。
- mode:決定了打開文件的模式:只讀,寫入,追加等。所有可取值見如下的完全列表。這個參數是非強制的,默認文件訪問模式爲只讀®
以下實例將字符串寫入到文件 foo.txt 中:
#!/usr/bin/python3
# 打開一個文件
f = open("/tmp/foo.txt", "w")
f.write( "Python 是一個非常好的語言。\n是的,的確非常好!!\n" )
# 關閉打開的文件
f.close()
此時打開文件 foo.txt,顯示如下:
$ cat /tmp/foo.txt
Python 是一個非常好的語言。
是的,的確非常好!!
文件對象的方法
f.read()
爲了讀取一個文件的內容,調用 f.read(size), 這將讀取一定數目的數據, 然後作爲字符串或字節對象返回。
size 是一個可選的數字類型的參數。 當 size 被忽略了或者爲負, 那麼該文件的所有內容都將被讀取並且返回。
#!/usr/bin/python3
# 打開一個文件
f = open("/tmp/foo.txt", "r")
str = f.read()
print(str)
# 關閉打開的文件
f.close()
執行以上程序,輸出結果爲:
Python 是一個非常好的語言。
是的,的確非常好!!
f.readline() 會從文件中讀取單獨的一行。換行符爲 ‘\n’。f.readline() 如果返回一個空字符串, 說明已經已經讀取到最後一行。
二、python3 錯誤和異常
Python 有兩種錯誤很容易辨認:語法錯誤和異常(Python assert(斷言)用於判斷一個表達式,在表達式條件爲 false 的時候觸發異常)
異常
即便 Python 程序的語法是正確的,在運行它的時候,也有可能發生錯誤。運行期檢測到的錯誤被稱爲異常。
大多數的異常都不會被程序處理,都以錯誤信息的形式展現在這裏:
>>>10 * (1/0) # 0 不能作爲除數,觸發異常
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ZeroDivisionError: division by zero
>>> 4 + spam*3 # spam 未定義,觸發異常
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'spam' is not defined
>>> '2' + 2 # int 不能與 str 相加,觸發異常
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: Can't convert 'int' object to str implicitly
異常以不同的類型出現,這些類型都作爲信息的一部分打印出來: 例子中的類型有 ZeroDivisionError,NameError 和 TypeError。
異常處理
異常捕捉可以使用 try/except 語句
while True:
try:
x = int(input("請輸入一個數字: "))
break
except ValueError:
print("您輸入的不是數字,請再次嘗試輸入!")
try 語句按照如下方式工作:
- 首先,執行 try 子句(在關鍵字 try 和關鍵字 except 之間的語句)
- 如果沒有異常發生,忽略 except 子句,try 子句執行後結束
- 如果在執行 try 子句的過程中發生了異常,那麼 try 子句餘下的部分將被忽略。如果異常的類型和 except 之後的名稱相符,那麼對應的 except 子句將被執行
- 如果一個異常沒有與任何的 excep 匹配,那麼這個異常將會傳遞給上層的 try 中
一個 try 語句可能包含多個except子句,分別來處理不同的特定的異常。最多隻有一個分支會被執行,一個except子句可以同時處理多個異常,這些異常將被放在一個括號裏成爲一個元組。
最後一個except子句可以忽略異常的名稱,它將被當作通配符使用。你可以使用這種方法打印一個錯誤信息,然後再次把異常拋出。
import sys
try:
f = open('myfile.txt')
s = f.readline()
i = int(s.strip())
except OSError as err:
print("OS error: {0}".format(err))
except ValueError:
print("Could not convert data to an integer.")
except:
print("Unexpected error:", sys.exc_info()[0])
raise
try/except…else
try-finally 語句
拋出異常raise 語句
以下實例如果 x 大於 5 就觸發異常
x = 10
if x > 5:
raise Exception('x 不能大於 5。x 的值爲: {}'.format(x))
用戶自定義異常
你可以通過創建一個新的異常類來擁有自己的異常。異常類繼承自 Exception 類,可以直接繼承,或者間接繼承
關鍵詞 with 語句就可以保證諸如文件之類的對象在使用完之後一定會正確的執行他的清理方法:
with open("myfile.txt") as f:
for line in f:
print(line, end="")
二、面向對象
- 類(Class): 用來描述具有相同的屬性和方法的對象的集合。它定義了該集合中每個對象所共有的屬性和方法。對象是類的實例。
- 方法:類中定義的函數
- 類變量:類變量在整個實例化的對象中是公用的。類變量定義在類中且在函數體之外。類變量通常不作爲實例變量使用
- 數據成員:類變量或者實例變量用於處理類及其實例對象的相關的數據
- 方法重寫:如果從父類繼承的方法不能滿足子類的需求,可以對其進行改寫,這個過程叫方法的覆蓋(override),也稱爲方法的重寫
- 局部變量:定義在方法中的變量,只作用於當前實例的類
- 實例變量:在類的聲明中,屬性是用變量來表示的,這種變量就稱爲實例變量,實例變量就是一個用 self 修飾的變量
- 繼承:即一個派生類(derived class)繼承基類(base class)的字段和方法。繼承也允許把一個派生類的對象作爲一個基類對象對待。
- 實例化:創建一個類的實例,類的具體對象
- 對象:通過類定義的數據結構實例。對象包括兩個數據成員(類變量和實例變量)和方法
Python中的類提供了面向對象編程的所有基本功能:類的繼承機制允許多個基類,派生類可以覆蓋基類中的任何方法,方法中可以調用基類中的同名方法。
類對象
類對象支持兩種操作:屬性引用和實例化。
#!/usr/bin/python3
class MyClass:
"""一個簡單的類實例"""
i = 12345
def f(self):
return 'hello world'
# 實例化類
x = MyClass()
# 訪問類的屬性和方法
print("MyClass 類的屬性 i 爲:", x.i)
print("MyClass 類的方法 f 輸出爲:", x.f())
類有一個名爲 init() 的特殊方法(構造方法),該方法在類實例化時會自動調用,像下面這樣:
def __init__(self):
self.data = []
類定義了 init() 方法,類的實例化操作會自動調用 init() 方法。如下實例化類 MyClass,對應的 init() 方法就會被調用, init() 方法可以有參數,參數通過 init() 傳遞到類的實例化操作上。
#!/usr/bin/python3
class Complex:
def __init__(self, realpart, imagpart):
self.r = realpart
self.i = imagpart
x = Complex(3.0, -4.5)
print(x.r, x.i) # 輸出結果:3.0 -4.5
self代表類的實例,而非類,類的方法與普通的函數只有一個特別的區別——它們必須有一個額外的第一個參數名稱, 按照慣例它的名稱是 self。
class Test:
def prt(self):
print(self)
print(self.__class__)
t = Test()
t.prt()
以上實例執行結果爲:
<__main__.Test instance at 0x100771878>
__main__.Test
self 代表的是類的實例,代表當前對象的地址,而 self.class 則指向類
類的方法
在類的內部,使用 def 關鍵字來定義一個方法,與一般函數定義不同,類方法必須包含參數 self, 且爲第一個參數,self 代表的是類的實例。
#!/usr/bin/python3
#類定義
class people:
#定義基本屬性
name = ''
age = 0
#定義私有屬性,私有屬性在類外部無法直接進行訪問
__weight = 0
#定義構造方法
def __init__(self,n,a,w):
self.name = n
self.age = a
self.__weight = w
def speak(self):
print("%s 說: 我 %d 歲。" %(self.name,self.age))
# 實例化類
p = people('runoob',10,30)
p.speak()
執行以上程序輸出結果爲:
runoob 說: 我 10 歲。
繼承
class DerivedClassName(BaseClassName1):
<statement-1>
.
.
.
<statement-N>
方法重寫
如果你的父類方法的功能不能滿足你的需求,你可以在子類重寫你父類的方法,實例如下:
#!/usr/bin/python3
class Parent: # 定義父類
def myMethod(self):
print ('調用父類方法')
class Child(Parent): # 定義子類
def myMethod(self):
print ('調用子類方法')
c = Child() # 子類實例
c.myMethod() # 子類調用重寫方法
super(Child,c).myMethod() #用子類對象調用父類已被覆蓋的方法
類屬性與方法
類的私有屬性:
__private_attrs:兩個下劃線開頭,聲明該屬性爲私有,不能在類的外部被使用或直接訪問。在類內部的方法中使用時 self.__private_attrs。
類的方法:
在類的內部,使用 def 關鍵字來定義一個方法,與一般函數定義不同,類方法必須包含參數 self,且爲第一個參數,self 代表的是類的實例。
類的私有方法:
兩個下劃線開頭,聲明該方法爲私有方法,只能在類的內部調用 ,不能在類的外部調用。self.__private_methods
#!/usr/bin/python3
class JustCounter:
__secretCount = 0 # 私有變量
publicCount = 0 # 公開變量
def count(self):
self.__secretCount += 1
self.publicCount += 1
print (self.__secretCount)
counter = JustCounter()
counter.count()
counter.count()
print (counter.publicCount)
print (counter.__secretCount) # 報錯,實例不能訪問私有變量
三、Python3 命名空間和作用域
一個文件夾(目錄)中可以包含多個文件夾,每個文件夾中不能有相同的文件名,但不同文件夾中的文件可以重名。
一般有三種命名空間:
- 內置名稱(built-in names), Python 語言內置的名稱,比如函數名 abs、char 和異常名稱 BaseException、Exception 等等
- 全局名稱(global names),模塊中定義的名稱,記錄了模塊的變量,包括函數、類、其它導入的模塊、模塊級的變量和常量
- 局部名稱(local names),函數中定義的名稱,記錄了函數的變量,包括函數的參數和局部定義的變量
Python 的查找順序爲:局部的命名空間去 -> 全局命名空間 -> 內置命名空間
全局變量和局部變量(定義在函數內部的變量擁有一個局部作用域,定義在函數外的擁有全局作用域;局部變量只能在其被聲明的函數內部訪問,而全局變量可以在整個程序範圍內訪問)
#!/usr/bin/python3
total = 0 # 這是一個全局變量
# 可寫函數說明
def sum( arg1, arg2 ):
#返回2個參數的和."
total = arg1 + arg2 # total在這裏是局部變量.
print ("函數內是局部變量 : ", total)
return total
#調用sum函數
sum( 10, 20 )
print ("函數外是全局變量 : ", total)
global 和 nonlocal關鍵字
當內部作用域想修改外部作用域的變量時,就要用到global和nonlocal關鍵字
如果要修改嵌套作用域(enclosing 作用域,外層非全局作用域)中的變量則需要 nonlocal 關鍵字