python day5

python day5

面向对象高级编程

使用slots

动态绑定允许在class之外给类添加属性和方法。
如果要对这种动态绑定加限制,用__slots__

class Student(object):
    __slots__ = ('name', 'age')
    #使用元组定义允许使用动态绑定的属性

没有被放入__slots__的不允许动态绑定。
子类不受影响。
如果子类也有__slots__,则子类和父类__slots__定义的都允许动态绑定。

__slots__可以大大减少内存的占用。因为对象属性是依靠字典存储的。而__slots__可以减少对内存的负担。

__slots__需要对每一个继承对子类都重新定义一遍;而且不够灵活。

除非编写的类会有上万个对象,否则不推荐使用。

@property

装饰器
把方法变成属性调用
在get方法前加上@property,方法变成属性;自动生成另一个装饰器@属性.setter。

class Student(object):

    @property
    def get_gender(self):
        return self.__gender

    def set_gender(self, gender):
        if gender == 'male' or gender == 'female':
            self.__gender = gender
        else:
            raise ValueError('invalid gender')


s = Student
s.gender = 'male'
print(s.gender)

减少调用者的负担

多重继承

Java的多继承是用接口实现的。
python 通过继承多个类实现MixIn。

class Dog(Mammal, Animal,  Runnable):
    pass

python 多重继承的拓扑排序:
https://kevinguo.me/2018/01/19/python-topological-sorting/
使用C3 算法。
继承关系是一个有向无环图,从入度为0处开始,如果多个入度为0,则取最左。

定制类

__str__()用户看
__repr__()调试看
改变控制台打印的信息
一般__repr__ == __str__
__iter__()方法返回迭代对象

__getitem__()
__setitem__()
__delitem__()
将自己定义的类表现的与list、tuple、dict没什么区别。

__getattr__()
动态获取类的属性
如果在调用类的属性时,没有该属性,那么会取调用这个方法。
__getattr__()默认返回None。

__call__()
使得对象变得可以被调用
callable()判断一个对象是否是可以被调用的对象。

枚举类

可以直接使用enum,也可以定义自己的枚举类。

# coding _utf-8

from enum import Enum

Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))

for name, member in Month.__members__.items():
    print(name, '==>', member, ',', member.value)#value默认从1开始。
('Jan', '==>', <Month.Jan: 1>, ',', 1)
('Feb', '==>', <Month.Feb: 2>, ',', 2)
('Mar', '==>', <Month.Mar: 3>, ',', 3)
('Apr', '==>', <Month.Apr: 4>, ',', 4)
('May', '==>', <Month.May: 5>, ',', 5)
('Jun', '==>', <Month.Jun: 6>, ',', 6)
('Jul', '==>', <Month.Jul: 7>, ',', 7)
('Aug', '==>', <Month.Aug: 8>, ',', 8)
('Sep', '==>', <Month.Sep: 9>, ',', 9)
('Oct', '==>', <Month.Oct: 10>, ',', 10)
('Nov', '==>', <Month.Nov: 11>, ',', 11)
('Dec', '==>', <Month.Dec: 12>, ',', 12)

在pycharm中无法导入enum模块,最后清除缓存,重启。

自定义枚举类型:

from enum import Enum, unique

unique
class Month(Enum):
    Jan = 0#value可以自己编写
    Feb = 1
    Mar = 2
    Apr = 3
    May = 4
    Jun = 5
    Jul = 6
    Aug = 7
    Sep = 8
    Oct = 9
    Nov = 10
    Dec = 11

@unique保证value不会重复。

使用元类

type()

type()可以检查一个对象或者变量的类型,也可以动态创建一个类。
类的类型是type。

metaclass

类似于元数据的概念。
元类。
定义元类,就可以根据元类创建类,然后根据类创建对象。

错误、调试、测试

修复bug、检查用户输入、处理异常、测试代码

错误处理

Java是try...catch...finally
python是try...except...finally
或者try...except...else...finally

python所有的错误都继承自BaseException。
java throw
python raise
如果不带参数,raise将错误原样抛出。

调试

assert
断言,调试结束可以关闭

logging

级别:
debug
info
warning
error

import logging
logging.basicConfig(level=logging.ERROR)

s = '0'
n = int(s)
logging.info('n = %d' % n)
print(10 / n)

logging调试最强大,ide调试最方便

单元测试

# -*- coding: utf-8 -*-
import unittest

class Student(object):
    def __init__(self, name, score):
        self.name = name
        if not (score >= 0 and score <= 100):
            raise ValueError('invalid score')
        self.score = score

    def get_grade(self):
        if self.score >= 80:
            return 'A'
        elif self.score >= 60:
            return 'B'
        return 'C'


class TestStudent(unittest.TestCase):

    def test_80_to_100(self):
        s1 = Student('Bart', 80)
        s2 = Student('Lisa', 100)
        self.assertEqual(s1.get_grade(), 'A')
        self.assertEqual(s2.get_grade(), 'A')

    def test_60_to_80(self):
        s1 = Student('Bart', 60)
        s2 = Student('Lisa', 79)
        self.assertEqual(s1.get_grade(), 'B')
        self.assertEqual(s2.get_grade(), 'B')

    def test_0_to_60(self):
        s1 = Student('Bart', 0)
        s2 = Student('Lisa', 59)
        self.assertEqual(s1.get_grade(), 'C')
        self.assertEqual(s2.get_grade(), 'C')

    def test_invalid(self):
        s1 = Student('Bart', -1)
        s2 = Student('Lisa', 101)
        with self.assertRaises(ValueError):
            s1.get_grade()
        with self.assertRaises(ValueError):
            s2.get_grade()

if __name__ == '__main__':
    unittest.main()

文档测试

文档测试既可以测试,也可以作为示例程序。

IO

分为:
同步IO:效率低,简单
异步IO:效率高,复杂,有轮询模式和回调模式
本质上是高效的cpu与低效的外设之间的矛盾

文件读写

读input

try:
    f = open('haha.txt', 'r')#r表示读
    f.read()
except IOError as e:
    pass
finally:
    if f:
        f.close()

读进来的数据是一个str类型的对象。
比较麻烦
简写方式是:

with open('haha.txt', 'r') as f:
    f.read()

read() 一次性读取文件的全部数据
read(size) 一次最多读取size字节的数据
readline() 一次读取一行数据
readlines() 一次读取全部数据,并返回list,按照行存储所有的数据

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值