Python - 類變量/對象變量/繼承/讀寫文件/異常

類變量與對象變量

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.

“編寫一款你自己的命令行地址簿程序,你可以用它瀏覽、添加、編輯、刪除或搜索你的聯(lián)系人,例如你的朋友、家人、同事,還有他們諸如郵件地址、電話號碼等多種信息。這些詳細信息必須被妥善儲存以備稍后的檢索。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容