類變量與對象變量
class Robot:
population = 0 #類變量:用類名加點的方式調(diào)用
def __init__(self,name):
self.name = name #對象變量 : 只在本類中使用
print("(Initializing{})".format(self.name))
Robot.population += 1
def die(self):
print("{} is being destroyed".format(self.name))
#Robot.population -= 1
self.__class__.population -= 1
if Robot.population == 0:
print("{} was the last one".format(self.name))
else:
print("There are still {:d} robots working".format(Robot.population))
def say_hi(self):
'''來自機器人的真摯問候'''
print('Greetings,my master call me{}'.format(self.name))
@classmethod #類方法
def how_many(cls):
'''打印出當前的人口數(shù)量'''
print(cls.population)
#調(diào)用
droid1 = Robot('R2-D2')
droid1.say_hi()
droid1.how_many()
droid1 = Robot('C-3PO')
droid1.say_hi()
droid1.how_many()
(InitializingR2-D2)
Greetings,my master call meR2-D2
1
(InitializingC-3PO)
Greetings,my master call meC-3PO
2
#調(diào)用die()方法
droid1.die()
droid1.die()
C-3PO is being destroyed
There are still 1 robots working
C-3PO is being destroyed
C-3PO was the last one
#調(diào)用機器人數(shù)量
Robot.how_many()
0
Robot.say_hi.__doc__ ##方法文檔
'來自機器人的真摯問候'
繼承
#父類/基類/super類
class SchoolMember:
'''代表任何學校里的成員'''
def __init__(self,name,age):
self.name = name
self.age = age
# print('Initialized SchoolMember:{}'.format(self.name))
def tell(self):
'''告訴我有關我的細節(jié)'''
# end = “目的是打印一行并允許下一次打印在同一行繼續(xù)”
print('Name:"{}" Age:"{}"'.format(self.name,self.age),end = " ")
#子類/派生類
class Teacher(SchoolMember):
'''代表一位老師'''
def __init__(self,name,age,salary):
SchoolMember.__init__(self,name,age)
self.salary = salary
print('Inintialized Teacher:{}'.format(self.name))
def tell(self):
SchoolMember.tell(self)
print('Teacher - Salary:"{:d}"'.format(self.salary))
#子類/派生類
class Student(SchoolMember):
'''代表一位學生'''
def __init__(self,name,age,marks):
# SchoolMember.__init__(self,name,age)
self.name = name
self.age = age
self.marks = marks
print("Initalized Student : {}".format(self.name))
def tell(self):
SchoolMember.tell(self)
print('Student - Marks {}'.format(self.marks))
t = Teacher("老師1號",30,30000)
s = Student('學生1號',15,75)
Inintialized Teacher:老師1號
Initalized Student : 學生1號
members = [t,s]
for member in members:
member.tell()
Name:"老師1號" Age:"30"
Teacher - Salary:"30000"
Name:"學生1號" Age:"15"
Student - Marks 75
輸入與輸出
s = input() #用戶輸入
#width -- 指定填充指定字符后中字符串的總長度.
#fillchar -- 填充的字符,默認為空格。
print("s---" + s.rjust(10,"#")) #補上9個# 長度湊10
input == 1
s---#########1
“創(chuàng)建、讀取與寫入文件”
def reverse(text):
print('text == '+ text)
print('倒序text == ' + text[::-1])
return text[::-1] #倒敘排列
def is_palindrome(text):
return text == reverse(text)
something = input("Enter text")
if is_palindrome(something):
print("Yes,it's a palindrome")
else:
print("No. it's not a palondrome")
Enter textabcba
text == abcba
倒序text == abcba
Yes,it's a palindrome
#練習 去掉標點
str1 = "Rise to vote, sir"
str2 = ""
list1 = str1[:]
for chars in list1:
if chars not in (",",".","...","?","!"):
str2 += chars
print (str2)
Rise to vote sir
文件的讀取/寫入
- r - 讀取
- w - 寫入會覆蓋原有內(nèi)容
- a - 追加
- t - 文本模式
- b - 二進制模式
poem ='''Programming is fun
When the work is done
if you wanna make your work also fun:
use Python!'''
#打開文件以編輯 w - write
f = open('/Users/name/Desktop/Podfile.text','w')
#向文件中編寫文本
f.write(poem)
#關閉文件
f.close()
#默認是讀 r - read
f1 = open('/Users/name/Desktop/Podfile.text')
while True:
line = f1.readline()
#零長度只是說明已經(jīng)到了末尾
if len(line) == 0:
break
print (line,end = " ")
f1.close()
Programming is fun
When the work is done
if you wanna make your work also fun:
use Python!
Pickle
- “可以將任何純 Python 對象存儲到一個文件中,并在稍后將其取回”
- “持久地(Persistently)存儲對象”
import pickle
shoplistfile = '/Users/name/Desktop/Podfile.text'
shoplist = ['apple','mango','carrot']
# 'wb' - 寫入二進制文件
p = open(shoplistfile,'wb')
pickle.dump(shoplist,p)
f.close()
del shoplist
# 'rb' - 讀取二進制文件
p = open(shoplistfile,'rb')
storedlist = pickle.load(p)
print(storedlist)
['apple', 'mango', 'carrot']
Unicode
import io
uf = io.open('/Users/name/Desktop/Podfile.text','wt',encoding='utf-8')
uf.write(u'Imagine non-English language here')
uf.close()
text = io.open('/Users/name/Desktop/Podfile.text',encoding='utf-8').read()
print(text)
Imagine non-English language here
異常
try:
text = input('Enter something -->')
except EoFError:
print('Why did you do an EOF on me?')
except KeyboardInterrupt:
print('You cancelled the operation')
else:
print('You entered{}'.format(text))
Enter something -->
You entered
拋出異常
521512625218_.pic.jpg

- 通過
raise語句來引發(fā)一次異常,具體方法是提供錯誤名或異常名以及要拋出(Thrown)異常的對象。 - “你能夠引發(fā)的錯誤或異常必須是直接或間接從屬于 Exception(異常) 類的派生類。”
class ShortInputException(Exception):
'''一個由用戶定義的異常類'''
def __init__(self,length,atleast):
Exception.__init__(self)
#輸入文字長度
self.length = length
#“期望的最小長度”
self.atleast = atleast
try:
text = input('Enter something -->')
if len(text) < 3:
raise ShortInputException(len(text),3)
# 其他工作能在此處繼續(xù)正常運行”
except EOFError:
print('Why did you do an EOF on me?')
except ShortInputException as ex:
print(('ShortInputException: The input was ' + '{0} long, expected at least {1}').format(ex.length, ex.atleast))
else:
print('No exception was raised')
Enter something -->abc
No exception was raised
Try ... Finally
- “確保文件對象被正確關閉”
import sys,time
tf = None
try:
tf = open('/Users/name/Desktop/Podfile.text')
while True:
line = tf.readline()
if len(line) == 0 :
break
print (line, end = "")
#立即打印到屏幕上
sys.stdout.flush()
print('Press ctrl + c Now')
time.sleep(2)
except IOError:
print("Could not find file poem.txt")
except KeyboardInterrupt:
print("!! You cancelled the reading from the file.")
finally:#無論何種錯誤都會執(zhí)行關閉 釋放資源
if tf:
tf.close()
print("(Cleaning up: Closed the file)")
Imagine non-English language herePress ctrl + c Now
(Cleaning up: Closed the file)
with 語句
- 釋放/關閉文件的操作交給 with open 自動完成
with open('/Users/name/Desktop/Podfile.text') as wf:
for line in wf:
print(line,end="")
Imagine non-English language here
傳遞元組
- 當一個函數(shù)中返回兩個不同的值時,就會直接返回一個元組
def get_errir_details():
return(2,'details')
errnum,errstr = get_errir_details()
print('errnum== '+ str(errnum))
print('errstr== '+ errstr)
errnum== 2
errstr== details
交換兩個變量的最快方法
a = 5
b = 8
a,b = b,a
a,b
(8, 5)
特殊方法
-
__init__(self, ...)在新創(chuàng)建的對象被返回準備使用時被調(diào)用 -
__del__(self)這一方法在對象被刪除之前調(diào)用(它的使用時機不可預測,所以避免使用它) -
__str__(self)當我們使用 print 函數(shù)時,或 str() 被使用時就會被調(diào)用 -
__lt__(self, other)當小于運算符(<)被使用時被調(diào)用。類似地,使用其它所有運算符(+、> 等等)時都會有特殊方法被調(diào)用. -
__getitem__(self, key)使用 x[key] 索引操作時會被調(diào)用 -
__len__(self)當針對序列對象使用內(nèi)置 len() 函數(shù)時會被調(diào)用
函數(shù)接受可變參數(shù) - 參數(shù)數(shù)目不確定
- 參數(shù)前加一個 * ,函數(shù)的所有其它的額外參數(shù)都將傳遞到 args 中,并作為一個元組予以儲存
- 參數(shù)前加兩個 * ,額外的參數(shù)將被視為字典的鍵值—值配對
def powersum(power, *args):
'''Return the sum of each argument raised to the specified power.'''
total = 0
for i in args:
total += pow(i, power)
return total
print(powersum(2, 3, 4))
print(powersum(2, 10))
25
100
assert 語句 -- 斷言
-
如果沒有特別的目的,斷言應該用于如下情況:
- 防御性的編程
- 運行時對程序邏輯的檢測
- 合約性檢查(比如前置條件,后置條件)
- 程序中的常量
- 檢查文檔
assert 語句用以斷言(Assert)某事是真的
大多數(shù)情況下,它好過捕獲異常,也好過定位問題或向用戶顯示錯誤信息然后退出。
當語句斷言失敗時,將會拋出 AssertionError。
mylist = ['item']
assert len(mylist) >= 1
mylist.pop()
'item'
assert len(mylist) >= 1
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-110-0061aada0cbf> in <module>()
----> 1 assert len(mylist) >= 1
AssertionError:
class Account(object):
def __init__(self,number):
self.number = number
self.balance = 0
def deposit(self,amount):
assert amount>0
self.balance += balance
def withdraw(self,amount):
assert amount>0
if amount <= self.balance:
self.balance -= amount
else:
print('balance is not enough')
if __name__ == "__main__":
a = Account(1000)
a.deposit(-10)
程序中,deposit()和withdraw()方法的參數(shù) amount 值必須大于0的,這就是斷言的作用,不滿足就報錯。
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-9-4ed7ce52d5ce> in <module>()
14 if __name__ == "__main__":
15 a = Account(1000)
---> 16 a.deposit(-10)
<ipython-input-9-4ed7ce52d5ce> in deposit(self, amount)
4 self.balance = 0
5 def deposit(self,amount):
----> 6 assert amount>0
7 self.balance += balance
8 def withdraw(self,amount):
AssertionError:
裝飾器
- 應用包裝函數(shù)的快捷方式
- 這有助于將某一功能與一些代碼一遍又一遍地“包裝”
from time import sleep
from functools import wraps
import logging
logging.basicConfig()
log = logging.getLogger('retry')
def retry(f):
@wraps(f)
def wrapped_f(*args,**kwargs):
MAX_ATTEMPTS = 5
for attempt in range(1, MAX_ATTEMPTS + 1):
try:
return f(*args, **kwargs)
except:
log.exception("Attempt %s/%s failed : %s",
attempt,
MAX_ATTEMPTS,
(args, kwargs))
sleep(10 * attempt)
log.critical("All %s attempts failed : %s",
MAX_ATTEMPTS,
(args, kwargs))
return wrapped_f
counter = 0
@retry
def save_to_database(arg):
print("Write to a database or make a network call or etc.")
print("This will be automatically retried if exception is thrown.")
global counter
counter += 1
# 這將在第一次調(diào)用時拋出異常
# 在第二次運行時將正常工作(也就是重試)
if counter < 2:
raise ValueError(arg)
if __name__ == '__main__':
save_to_database("Some bad value")
ERROR:retry:Attempt 1/5 failed : (('Some bad value',), {})
Traceback (most recent call last):
File "<ipython-input-1-dbbe5f071215>", line 14, in wrapped_f
return f(*args, **kwargs)
File "<ipython-input-1-dbbe5f071215>", line 37, in save_to_database
raise ValueError(arg)
ValueError: Some bad value
Write to a database or make a network call or etc.
This will be automatically retried if exception is thrown.
Write to a database or make a network call or etc.
This will be automatically retried if exception is thrown.