Python - 类变量/对象变量/继承/读写文件/异常

类变量与对象变量

class Robot:
    population = 0 #类变量:用类名加点的方式调用
    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):
        '''打印出当前的人口数量'''
        print(cls.population)


#调用
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

#调用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

#调用机器人数量
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):
        '''告诉我有关我的细节'''
        # end =  “目的是打印一行并允许下一次打印在同一行继续”
        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

“创建、读取与写入文件”

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 - 写入会覆盖原有内容
  • 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()
    #零长度只是说明已经到了末尾
    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

抛出异常
Python - 类变量/对象变量/继承/读写文件/异常_第1张图片
521512625218_.pic.jpg

  • 通过 raise 语句来引发一次异常,具体方法是提供错误名或异常名以及要抛出(Thrown)异常的对象。
  • “你能够引发的错误或异常必须是直接或间接从属于 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)
    # 其他工作能在此处继续正常运行”
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:#无论何种错误都会执行关闭 释放资源
    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

传递元组

  • 当一个函数中返回两个不同的值时,就会直接返回一个元组
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, ...)在新创建的对象被返回准备使用时被调用
  • __del__(self)这一方法在对象被删除之前调用(它的使用时机不可预测,所以避免使用它)
  • __str__(self)当我们使用 print 函数时,或 str() 被使用时就会被调用
  • __lt__(self, other) 当小于运算符(<)被使用时被调用。类似地,使用其它所有运算符(+、> 等等)时都会有特殊方法被调用.
  • __getitem__(self, key)使用 x[key] 索引操作时会被调用
  • __len__(self)当针对序列对象使用内置 len() 函数时会被调用

函数接受可变参数 - 参数数目不确定

  • 参数前加一个 * ,函数的所有其它的额外参数都将传递到 args 中,并作为一个元组予以储存
  • 参数前加两个 * ,额外的参数将被视为字典的键值—值配对
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)某事是真的

  • 大多数情况下,它好过捕获异常,也好过定位问题或向用户显示错误信息然后退出。

  • 当语句断言失败时,将会抛出 AssertionError。

mylist = ['item']
assert len(mylist) >= 1
mylist.pop()
'item'
assert len(mylist) >= 1
---------------------------------------------------------------------------

AssertionError                            Traceback (most recent call last)

 in ()
----> 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()方法的参数 amount 值必须大于0的,这就是断言的作用,不满足就报错。

---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
 in ()
     14 if __name__ == "__main__":
     15     a = Account(1000)
---> 16     a.deposit(-10)

 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:

装饰器

  • 应用包装函数的快捷方式
  • 这有助于将某一功能与一些代码一遍又一遍地“包装”
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
    # 这将在第一次调用时抛出异常
    # 在第二次运行时将正常工作(也就是重试)
    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 "", line 14, in wrapped_f
    return f(*args, **kwargs)
  File "", 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.

“编写一款你自己的命令行地址簿程序,你可以用它浏览、添加、编辑、删除或搜索你的联系人,例如你的朋友、家人、同事,还有他们诸如邮件地址、电话号码等多种信息。这些详细信息必须被妥善储存以备稍后的检索。

你可能感兴趣的:(Python - 类变量/对象变量/继承/读写文件/异常)