Day04

9. 面向对象

9.4 继承与多态

在python这样的动态语言中,语法简单,即使是令人头疼的继承多态,也比较容易理解

  • 继承
    a继承,可以表示为:class a(b):
    其他父类子类,继承规则等方面同C++,不再赘述
  • 多态
    多态对于python不像c++,java静态语言那般重要,因为即使没有类的继承关系,python也能够实现多态,比如以下代码
class m(object):
    def __init__(self, a, b):
        m.__a = a
        m.__b = b

    def run(self):
        print(f'({m.__a},{m.__b})')


class n(object):
    def __init__(self, a, b):
        m.__a = a
        m.__b = b

    def run(self):
        print("(%c,%c)" % (m.__a, m.__b))


def running(a):
    a.run()


a1 = m(1, 2)
a2 = n('a', 'b')
running(a1)
running(a2)

结果是
(1,2)
(a,b)

running只是一个普通函数,m和n是两个独立的类,没有继承关系,但能够将这两种不同的类传入(只要含有run()的方法),实现了多态

9.5 实例属性与类属性

直接在class中定义属性,这种属性是类属性,归类所有

class m:
    name = "cc"


a1 = m()
a2 = m()
print(a1.name)
print(a2.name)

结果是

cc
cc
9.6 修饰器与静态方法
  • __slots__
    动态语言允许在程序运行过程中给类添加新的方法,给实例添加的方法其他实例无法使用,给类添加的方法所有实例都能使用
    __slots__限定的类不能够再添加新的方法,用法:
    __slots__ = ('_name', '_age', '_gender')
  • @property
class Student(object):
    @property
    def birth(self):
        return self._birth

    @birth.setter
    def birth(self, value):
        self._birth = value

    @property
    def age(self):
        return 2019 - self._birth


s = Student()
s.birth = 1999
print(s.age)
print(s._birth)
print(s.birth)
20
1999
1999

property修饰器将_birth这个属性包装了起来,通过birth.getter和birth.setter对于_birth进行修改和读取,这样的好处是能够在settter里进行输入检查,增加程序的健壮性

10. 模块

以下是一个模块的标准格式(当然不这么写当然可以)

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

有效的模块导入方式(减少码量)
import module_name as local_module_name
模块主函数的编写规范(写在主函数前)
if __name__=='__main__':
如果模块里有可执行代码,那么在import时就会执行,但这不是我们所希望的,加上这行代码的限定后,模块的主函数不会执行,对于这个模块就能够放心的导入了

11. 字典

很像哈希表的原理,通过键—值对的数据存储来简化数据的查找操作,不同的是哈希表有哈希函数来确定数据存储位置,且根据哈希函数的不同,有不同的地址冲突风险,且key值只能为数字,字典采取的是一一对应的结构,又类似于C++的map
举个栗子:

zidian = {
    'a': '阿',
    'w': '伟',
    's': '死',
    'l': '了',
}
for word in zidian.keys():
    print("%s: %s" % (word, zidian[word]))
for meaning in zidian.values():
    print("%s" % meaning, end='')
for a, b in zidian.items():
    print("(%s,%s)" % (a, b))

结果为:

a: 阿
w: 伟
s: 死
l: 了
阿伟死了
(a,阿)
(w,伟)
(s,死)
(l,了)

12.函数

(好像学习顺序出了点错,不过不用在意)

12.1基础函数
def chouka(money):
    if(money<638):
        return "无"
    else:
        return "SSR"

既没有返回值类型,又没有形参的数据类型

12.2 高阶函数

函数的函数
将函数名作为参数传入函数(太神奇了吧!!!)

import math
def add(x, y, f):
    return f(x) + f(y)

print(add(-2,3,abs))
print(add(4,9,math.sqrt))

结果为

5
5.0
12.3 位置参数和关键字参数

关键字参数的存在让我们不用再继续按照形参表上形参的位置来传递参数
混合参数的格式为:位置参数在前,关键字参数在后

def add(a, b, c, d, e):
    print(a, b, c, d, e)


add(1, 2, 3, e=5, d=4)
12.4 几种有用的函数

map()

def f(x):
    return x * x


r = map(f, [1, 2, 3, 4, 5])
print(tuple(r))
(1, 4, 9, 16, 25)

将列表,元组的每一个元素传入函数中,重新生成一个新的列表或者元组(当然用for循环其实也能做到)
sorted()
正如C++的sort快排函数一样,sorted函数也能够根据所需编写比较函数,格式:
sorted(a,key=cmp,reverse=True/False)

L = [('Bob', 70), ('Adam', 90), ('Bart', 60), ('Lisa', 80)]
L1 = sorted(L, key=lambda x: x[0])
L2 = sorted(L, key=lambda x: x[1])
print(L1)
print(L2)
[('Adam', 90), ('Bart', 60), ('Bob', 70), ('Lisa', 80)]
[('Bart', 60), ('Bob', 70), ('Lisa', 80), ('Adam', 90)]

13. 异常

  • try/except

在Python中,我们可以将那些在运行时可能会出现状况的代码放在try代码块中,在try代码块的后面可以跟上一个或多个except来捕获可能出现的异常状况

  • try/finally

无论异常是否发生,执行清理操作

finally后为必然执行的语句(无论前面是否发生错误),用了写关闭文件,释放外部资源这种重要语句

  • with/as

实现上下文管理器

自动关闭文件,防止忘记,减少代码量
上下文管理器的经典语句:

with open('123.txt') as f: 
    for line in f:
        print(line)
自定义异常

异常类继承Exception类
通过raise手动抛出异常:

class MathError(Exception):
    def __init__(self, a):
        self.value = a

    def __str__(self):
        return ("你的输入为" + str(self.value) + ",要求输入正整数")


def num_Test():
    try:
        num = float(input("请输入正整数:"))
        if num < 0 or num != round(num):
            raise MathError(num)
        else:
            print(int(num))

    except MathError as e:
        print(e)


while 1:
    num_Test()

你可能感兴趣的:(Day04)