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

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

作者: 丘山Ivan | 来源:发表于2017-12-04 17:24 被阅读32次

    类变量与对象变量

    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

    抛出异常 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)
    
    <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()方法的参数 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:
    

    装饰器

    • 应用包装函数的快捷方式
    • 这有助于将某一功能与一些代码一遍又一遍地“包装”
    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 "<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.
    

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

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/pyixixtx.html