2018-07-31 day12 面向对象

迭代器和生成器

生成器:

a.可以看成是一个可以存储多个数据的容器.需要里面数据的时候就生成一个,里面的数据只能从前往后依次生成,不能跳跃,不能从后往前.生成后的数据不能再生成

b.获取生成器中的数据用._next_()方法

c.函数声明中有yield关键字,函数就变成一个生成器

和列表比较:列表存数据,数据必须是实实在在的的数据,一个数据会占一定的内存空间
生成器存数据,存的是产生数据的算法,没有数据占内存空间

def Fibonacci(n):
    '''
    '''
    n1 = 1
    n2 = 1
    for x in range(1, n + 1):
        if x == 1 or x == 2:
            current = 1
            yield current
            continue
        current = n1 + n2
        n1, n2 = n2, current
        yield current


def main():
    '''
    生成器:
    a.可以看成是一个可以存储多个数据的容器.需要里面数据的时候就生成一个,里面的数据只能从前往后依次生成,不能跳跃,不能从后往前.生成后的数据不能再生成
    b.获取生成器中的数据用.__next__()方法
    c.函数声明中有yield关键字,函数就变成一个生成器

    和列表比较:列表存数据,数据必须是实实在在的的数据,一个数据会占一定的内存空间
    生成器存数据,存的是产生数据的算法,没有数据占内存空间
    '''
    x = (i for i in range(10))
    # x就是一个生成器,用来产生数据
    print(x)
    print(x.__next__())  # 获取生成器里面的数据(只能获取一个数据)
    print(x.__next__())
    print(x.__next__())
    print(x.__next__())  # 用完之后再调用__next__()会报StopIteration错误
    x = Fibonacci(10)
    print(x.__next__())
    print(x.__next__())
    print(x.__next__())
    print(x.__next__())
    print(x.__next__())


if __name__ == '__main__':
    main()

面向对象

  • 1.什么是类:对拥有同一属性和方法的对象的封装

    类是抽象的

    类中的相同属性是不能确定的

  • 2.什么是对象:对象就是类的实例

    对象是具体的

    对象的属性是确定的

  • 3.面向对象编程

    面向过程编程:一步一步写代码实现功能→工具:逻辑和算法

    函数式编程:面对问题考虑有没有拥有某种功能函数→工具:函数

    面向对象编程:面对问题考虑有没有相应的对象来解决→工具:类和对象

类的声明

类的声明:
class 类名(父类):
    属性
    方法
  • class:python中声明类的关键字
  • 类名:标识符,首字母大写,驼峰式命名
  • (父类):类继承自其他的类,要写括号,括号里面是父类命,可省略
  • 属性:对象属性和类的字段 → 保存数据
  • 方法:实质就是声明在类中的函数 → 实现功能

  • 声明两个对象方法,需要使用对象来调用
  • 对象方法默认有一个self参数,调用的时候系统会自动传参数
  • 谁调用这个方法,self就是谁
class Person:
    '''类的说明'''

    # 声明两个对象方法,需要使用对象来调用
    # 对象方法默认有一个self参数,调用的时候系统会自动传参数
    # 谁调用这个方法,self就是谁
    def eat(self):
        print(self)
        print('吃饭呢!!!')

    def sleep(self):
        print(self)
        print('睡觉呢!!!')

声明对象

  • 通过类的构造方法取创建对象(系统自动生成的和类名相同的方法)

对象名 = 类名()

  • 类的对象可以通过.语法使用类中声名的方法和属性

方式:对象.方法()/对象.属性

if __name__ == '__main__':
    # 声明对象
    p1 = Person()
    print(p1)
    p1.eat()

    # 一个类可以有多个对象
    p2 = Person()
    # 对象可以调用对象方法
    print(p2)
    p2.sleep()

对象的属性

声明对象属性

class 类名:
    def __init__(self):
        self.属性名 = 初值
        self.属性名2 = 初值2
        self.属性名3 = 初值3
class Person:
    '''人类'''
  • init系统自带的方法,不能直接调用,通过类创建对象的时候系统会自动调用的方法
  • init方法的作用是对对象的属性进行初始化
  • 通过构造方法船舰对象的时候,一定要保证init方法中除了self以外,其他每个参数都有值
    def __init__(self, name='', age=0, gender='Female'):
        # 声明对象的属性
        print('++++++++')
        '''
        name,age,gender就是person类的对象属性,只能通过对象调用
        '''
        self.name = name
        self.age = age
        self.gender = gender
        self.height = 191


if __name__ == '__main__':
    # 注意构造方法中的参数是直接传给init方法的参数的
    p1 = Person('Shin', 21, 'Male')
    print(p1.name)
    print(p1.age)
    print(p1.height)

    p2 = Person('Kris', 18, 'Male')
    print(p2.name, p2.age, p2.gender, p2.height)

    p2 = Person('doge')
    p5 = Person(gender='male')

对象属性的增删查改

class Dog:
    '''狗类'''

    def __init__(self, age=1, color='red'):
        self.age = age
        self.color = color


def mian():
    d1 = Dog(0, 'white')
  • 1.查属性:对象.属性(属性不存在会报错)
  • 对象.getattribute(属性名)/getattr(对象,属性名str,默认值(不存在返回默认值,有默认值则不报错))
print(d1.age, d1.color)
print(d1.__getattribute__('age'))
print(getattr(d1, 'age'))
  • 2.改属性值:对象.属性 = 新值
  • 对象.setattr('属性名','值')
  • setattr(对象,属性名,新值)
d1.age = 4
print(d1.age)
d1.__setattr__('color', 'brown')
setattr(d1, 'age', 10)
  • 3.增加属性:对象.属性 = 值(属性不存在)
  • 注意属性是添加给对象的,不是给类
d1.name = '狗哥'
print(d1.name)
d1.__setattr__('type', '金毛')
setattr(d1, 'gender', '雄')
  • 4.删除对象属性:del 对象.属性
  • 注意:删除的是对象的属性,不影响这个类的其他对象
  • 对象.delattr(属性名)/delattr(对象,属性名)
del d1.color
# print(d1.color)
d1.__delattr__('name')
delattr(d1, 'gender')


class Student:
    def __init__(self, name='', age=18, gender='male'):
        self.name = name
        self.age = age
        self.gender = gender

    def study(self):
        print('%s学习呢!!!' % self.name)

case: 声明学生类,有属性:姓名,性别,年龄 方法:学习

1.声明学生类的对象,声明的时候给姓名,性别和年龄赋值

2.通过三种方式分别获取姓名,性别,年龄并打印

3.给学生对象添加一个电话属性

4.修改学生的年龄

5.删除学生性别


stu1 = Student('周润发', 20, 'Male')
print(stu1.name, stu1.__getattribute__('age'), getattr(stu1, 'gender', None))
setattr(stu1, 'tel', '123321123')
stu1.__setattr__('age', '40')
stu1.__delattr__('gender')
stu1.study()

if __name__ == '__main__':
    mian()

slots魔法

class Person:

slots的功能:就是约束类中对象的属性.

    __slots__ = ('name', 'age', 'height', 'id')

    def __init__(self, name='', age=0):
        self.name = name
        self.age = age

    # 自定义对象的打印格式
    # id():python内置函数,功能是获取变量地址
    def __str__(self):
        return self.name + ',' + str(self.age)


def main():
    p1 = Person('王根基', 15)
    p1.name = '小三'
    p1.height = 177
    print(p1)


if __name__ == '__main__':
    main()

类中的方法

  • 属性:对象的属性,类的字段(属性)

  • 对象属性:属于对象的,不同对象对应的值可能不一样(对象属性,通过对象使用)

  • 类的字段:声明在类里面 函数外面 类属性属于类(类的字段,通过类使用)

  • 方法:对象方法(方法),类方法,静态方法

  • 对象方法:自带一个self参数,一般要通过对象去调用

  • 类方法:

    1.使用@classmethod修饰

    2.自带一个cls参数,不传参,谁调用就指向谁

  • 静态方法:

    1.使用@staticmethod修饰函数

    2.没有默认参数

    3.只能通过类来调用

怎么选择用对象方法,类方法,静态方法?

  • 如果实现函数功能需要使用对象属性就声明对象方法
  • 如果实现函数功能需要使用类的字段或者调用类方法就声明类方法
  • 都不需要就声明静态方法
class Person:
    # number是类字段
    number = 0

    def __init__(self, name='', age=1):
        self.name = name
        self.age = age

    # eat 方法是对象方法
    def eat(self, food):
        print('%s吃%s' % (self.name, food))

    @classmethod
    def ruinEarth(cls):
        # cls指向调用这个方法的类,cls可以当作类来用
        p2 = cls('z3')  # 可以使用cls创建对象
        print(p2.name)
        print(cls.number)  # 可以通过cls使用类的自段
        print('魂淡')

    # 使用@staticmethod修饰静态方法,没有默认参数
    @staticmethod
    def saveWater():
        print('节约用水')


def main():
    # 类的字段要用类来使用
    print(Person.number)

    # 对象的属性要通过对象来使用
    p1 = Person('根基')
    print(p1.name)
    p1.eat('人')

    # 类方法通过类来调用
    Person.ruinEarth()

    # 静态方法通过类来调用
    Person.saveWater()


case1:班级类,属性:班级名,学生,功能添加学生,查找学生

case2:一个类,封装所有和数学运算相关的功能

class Student:
    def __init__(self, name='', age=10):
        self.name = name
        self.age = age

    def __str__(self):
        return 'name:'+str(self.name)+'   age:'+str(self.age)


class ClassA:
    def __init__(self, name='', students=None):
        self.name = name
        self.students = students

    def addStudent(self):
        stu = Student('渣渣辉', 18)
        self.students.append(stu)
        print('增加一个学生')

    def searcherStudent(self):
        for stu in self.students:
            print(stu)

    def __str__(self):
        return str(self.name)+str(self.students)


class mathMethod:
    def plus(self, x, y):
        return x + y

    def sub(self, x, y):
        return x - y

    def mul(self, x, y):
        return x * y

    def div(self, x, y):
        return x / y


cls1 = ClassA('py1805', [])
cls1.addStudent()
print(cls1.students[0])

if __name__ == '__main__':
    main()

作业

  • 1.声明一个电脑类:
    属性:品牌、颜色、内存大小
    方法:打游戏、写代码、看视频

    a.创建电脑类的对象,然后通过对象点的方式获取、修改、添加和删除它的属性
    b.通过attr相关方法去获取、修改、添加和删除它的属性

'''
 @Author: Kris Shin
 @Date: 2018-07-31 19:00:25
 @Last Modified by: Kris Shin
 @Last Modified time: 2018-07-31 19:00:25
    1.声明一个电脑类:
    属性:品牌、颜色、内存大小
    方法:打游戏、写代码、看视频

    a.创建电脑类的对象,然后通过对象点的方式获取、修改、添加和删除它的属性
    b.通过attr相关方法去获取、修改、添加和删除它的属性
'''


class Computer:
    def __init__(self, brand='', color='', memory=1):
        self.brand = brand
        self.color = color
        self.memory = memory

    def playGame(self):
        print('%s can playing game' % self.brand)

    def typeCodes(self):
        print('%s can typing code' % self.brand)

    def watchVideo(self):
        print('%s can watching video' % self.brand)


def main():
    # 创建对象
    cpt1 = Computer('God of war', 'black', 8)
    # 点语句获取值
    print(cpt1.brand, cpt1.color, cpt1.memory)
    # 增加属性
    cpt1.fans = 3
    print(cpt1.fans)
    # 修改属性
    cpt1.memory = 32
    print(cpt1.memory)
    # 删除属性
    del cpt1.fans
    # print(cpt1.fans)  # 报错computer对象没有fans属性

    cpt2 = Computer('Dell', 'sliver', 4)
    # getattr相关方法
    print(cpt2.__getattribute__('brand'))
    print(cpt2.__getattribute__('color'))
    print(getattr(cpt2, 'memory'))
    # setattr相关方法
    cpt2.__setattr__('fans', 2)
    print(cpt2.__getattribute__('fans'))
    # delattr 相关方法
    delattr(cpt2, 'fans')
    # print(getattr(cpt2,'fans'))  # 报错computer对象没有fans属性
    setattr(cpt2, 'color', 'white')
    print(cpt2.__getattribute__('color'))


if __name__ == '__main__':
    main()
  • 2.声明一个人的类和狗的类:
    狗的属性:名字、颜色、年龄 狗的方法:叫唤
    人的属性:名字、年龄、狗 人的方法:遛狗
    a.创建人的对象小明,让他拥有一条狗大黄,然后让小明去遛大黄
'''
 @Author: Kris Shin
 @Date: 2018-07-31 19:20:53
 @Last Modified by: Kris Shin
 @Last Modified time: 2018-07-31 19:20:53
2.声明一个人的类和狗的类:
狗的属性:名字、颜色、年龄  狗的方法:叫唤
人的属性:名字、年龄、狗   人的方法:遛狗
a.创建人的对象小明,让他拥有一条狗大黄,然后让小明去遛大黄
'''


class Dog(object):
    def __init__(self, name='', age=1, color=''):
        self.name = name
        self.age = age
        self.color = color

    def woof(self):
        print('%s is woofing' % self.name)


class Person(object):
    def __init__(self, name='', age=0, dog=Dog()):
        self.name = name
        self.age = age
        self.dog = dog

    def playWithDog(self):
        print('%s is playing with %s' % (self.name, self.dog.name))


def main():
    huang = Dog('大黄', color='brown')
    ming = Person('小明', 23, huang)
    ming.playWithDog()


if __name__ == '__main__':
    main()
  • 3.声明一个矩形类:
    属性:长、宽 方法:计算周长和面积
    a.创建不同的矩形,并且打印其周长和面积
'''
 @Author: Kris Shin
 @Date: 2018-07-31 19:32:19
 @Last Modified by: Kris Shin
 @Last Modified time: 2018-07-31 19:32:19
3.声明一个矩形类:
属性:长、宽   方法:计算周长和面积
a.创建不同的矩形,并且打印其周长和面积
'''


class Rect(object):
    def __init__(self, width=0, height=0):
        self.width = width
        self.height = height
        print('width:' + str(width) + '   height:' + str(height))

    def getArea(self):
        return str(self.width * self.height)

    def gerCLength(self):
        return str(2 * (self.height + self.width))


def main():
    rt1 = Rect(5, 6)
    rt2 = Rect(12, 19)
    rt3 = Rect(3.1415, 15.9876)
    rt4 = Rect(2, 6)
    rt5 = Rect(4, 4)
    print('rect1    area:' + rt1.getArea() + '  girth:' + rt1.gerCLength())
    print('rect2    area:' + rt2.getArea() + '  girth:' + rt2.gerCLength())
    print('rect3    area:' + rt3.getArea() + '  girth:' + rt3.gerCLength())
    print('rect4    area:' + rt4.getArea() + '  girth:' + rt4.gerCLength())
    print('rect5    area:' + rt5.getArea() + '  girth:' + rt5.gerCLength())


if __name__ == '__main__':
    main()
  • 4.创建一个学生类:
    属性:姓名,年龄,学号 方法:答到,展示学生信息
    创建一个班级类:
    属性:学生,班级名 方法:添加学生,删除学生,点名
'''
 @Author: Kris Shin
 @Date: 2018-07-31 19:42:49
 @Last Modified by: Kris Shin
 @Last Modified time: 2018-07-31 19:42:49
4.创建一个学生类:
属性:姓名,年龄,学号   方法:答到,展示学生信息
创建一个班级类:
属性:学生,班级名   方法:添加学生,删除学生,点名
'''


class Student(object):
    def __init__(self, name='', age=0, id=''):
        self.name = name
        self.age = age
        self.id = id

    def arriveAt(self):
        print(
            '%s %s %d %s is here!!' % (self.id, self.name, self.age, self.id))


class Class(object):
    def __init__(self, name='', students=[]):
        self.name = name
        self.students = students

    def addStu(self, stu=Student()):
        self.students.append(stu)
        print('add a student %s !!' % stu.name)

    def delStu(self, stu):
        self.students.remove(stu)
        print('del a student %s !!' % stu.name)

    def getStu(self):
        for i in range(len(self.students)):
            self.students[i].arriveAt()


def main():
    stu1 = Student(name='aaa', id='001', age=18)
    stu2 = Student('bbb', 20, '002')
    cls = Class("lala", [stu1])
    cls.addStu(stu2)
    stu3 = Student('liupi', 50, '003')
    cls.addStu(stu3)
    cls.delStu(stu1)
    cls.getStu()


if __name__ == '__main__':
    main()
  • 5.写一个类,封装所有和数学运算相关的功能(包含常用功能和常用值,例如:pi,e等)
'''
 @Author: Kris Shin
 @Date: 2018-07-31 20:06:47
 @Last Modified by: Kris Shin
 @Last Modified time: 2018-07-31 20:06:47
5.写一个类,封装所有和数学运算相关的功能(包含常用功能和常用值,例如:pi,e等)
'''


class MathMethod(object):
    e = 2.71
    pi = 3.14

    @staticmethod
    def addNums(*nums):
        rt = 0
        for i in range(len(nums)):
            rt += nums[i]
        return rt

    @staticmethod
    def subNums(*nums):
        rt = nums[0]
        for i in range(1, len(nums)):
            rt -= nums[i]
        return rt

    @staticmethod
    def mulNums(*nums):
        rt = 1
        for i in range(len(nums)):
            rt *= nums[i]
        return rt

    @staticmethod
    def divNums(*nums):
        for i in range(1, len(nums)):
            if not nums[i]:
                print('illegal calculate!!!')
                return -1
        if nums[0] == 0:
            rt = 0
        else:
            rt = nums[0]
            for i in range(1, len(nums)):
                rt /= nums[i]
            return rt


def main():
    mas = MathMethod
    print(mas.addNums(1, 2, 3, 4, 5, 7))
    print(mas.subNums(1, 2, 3, 4, 5, 7))
    print(mas.mulNums(1, 2, 3, 4, 5, 7))
    print(mas.divNums(1, 2, 3, 4, 5, 7))
    print('e', mas.e, '   pi', mas.pi)


if __name__ == '__main__':
    main()

6.写一个班级类,属性:班级名、学生;功能:添加学生、删除学生、根据姓名查看学生信息,展示班级的所有学生信息

'''
 @Author: Kris Shin
 @Date: 2018-07-31 20:36:37
 @Last Modified by: Kris Shin
 @Last Modified time: 2018-07-31 20:36:37
6.1.写一个班级类,属性:班级名、学生;功能:添加学生、删除学生、根据姓名查看学生信息,展示班级的所有学生信息
'''


class Student(object):
    def __init__(self, name='', age=0, id=''):
        self.name = name
        self.age = age
        self.id = id

    def ShowStu(self):
        print('%s %s %d %s' % (self.id, self.name, self.age, self.id))


class Class(object):
    def __init__(self, name='', students=[]):
        self.name = name
        self.students = students

    def addStu(self, stu=Student()):
        self.students.append(stu)
        print('add a student %s !!' % stu.name)

    def delStu(self, stu):
        self.students.remove(stu)
        print('del a student %s !!' % stu.name)

    def ShowStus(self):
        for i in range(len(self.students)):
            self.students[i].ShowStu()


def main():
    stu1 = Student(name='aaa', id='001', age=18)
    stu2 = Student('bbb', 20, '002')
    cls = Class("lala", [stu1])
    cls.addStu(stu2)
    stu3 = Student('liupi', 50, '003')
    cls.addStu(stu3)
    cls.delStu(stu1)
    cls.ShowStus()


if __name__ == '__main__':
    main()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容