生成器(generator)和迭代器(iterator):
生成器:a.可以看成是一个可以存储多个数据的容器。需要里面的数据的时候就生成一个,里面的数据只能从前往后一个一个的生成
不能跳跃,也不能从后往前。生成的数据,不能再生成了
b.获取生成器里面的数据,需要使用next()方法
c.只要函数中有yield关键字,函数就不再是一个单纯的函数了,而变成一个生成器。
和列表比较:列表存数据,数据必须是实实在在存在的数据,一个数据会战一定的内存空间。
生成器存数据,存的是产生数据的算法,没有数据去占内存空间
def fio(n):
pre_1 = 1
pre_2 = 1
for x in range(1, n):
if x == 1 or x == 2:
current = 1
yield current
continue
current = pre_1 + pre_2
pre_1, pre_2 = pre_2, current
yield current
fio = fio(10)
print(fio)
print(fio.__next__())
print(fio.__next__())
print(fio.__next__())
print(fio.__next__())
print(fio.__next__())
print(fio.__next__())
print(fio.__next__())
print(fio.__next__())
类和对象
1.什么是类:对拥有相同熟悉的方法的对象的封装
2.什么是对象:对象就是类的实例
类的声明:
class 类名(父类):
属性
方法
class:python中声明类的关键字
类名:驼峰式命名
():类要继承的其他的类,需要写括号,里面的内容是父类的名字。可以省略
属性:对象属性和类的字段 -- 保存数据
方法:是指就是声明在类中的函数 -- 实现功能
对象属性的增删改查:
1.增:
对象.属性 = 值(属性不存在)
2.删:
方法Ⅰ:del 对象.属性
方法Ⅱ:对象.delattr('属性名')
3.改:
方法Ⅰ:对象.属性 = 新值
方法Ⅱ:对象.setattr(属性名, 新值) 和 setattr(对象, 属性名, 新值)
4.查:
方法Ⅰ:对象.属性(如果属性不存在,会报错)
print(p1.age)
方法Ⅱ:对象.getattribute('属性名') 和 getattr(对象, 属性名, 默认值)
print(p1.getattribute('age'))
print(getattr(p1, 'age', '无名'))
slots魔法:
属性:对象的属性(属性)、类的属性(类的字段)
对象属性:属于对象的,不同对象对应的值可能不一样
类的字段:声明在类里面,函数外面。类的属性属于类(类的字段,通过类来使用)
方法:对象方法(方法)、类方法、静态函数
对象方法:自带一个self参数,一般通过对象去调用
类方法:1.使用@classmethod来修饰
2.自带一个cls参数,并且这个参数不用传参,谁来调用这个方法,cls就指向谁
3.类方法要通过类来调用
静态方法:1.使用@staticmethod
2.没有默认参数
3.静态方法通过类来调用
怎么选择用对象方法、类方法、静态方法
if 如果实现函数需要使用对象的属性,就声明成对象方法
elif 如果实现函数的功能需要使用类的字段或者调用类的方法,就声明成类方法
else 如果实现函数功能不需要使用对象的属性也不需要类的字段,就声明成静态方法
class Person:
# number 是类的字段
number = 0
# 约束类中的对象的属性即属性只能在__slots__中选,可少不可多
__slots__ = ('name', 'age', 'sex')
"""
对象属性的声明:
class 类名:
def __init__(self):
self.属性1 = 初值
self.属性2 = 初值
init方法是系统自带的一个方法,这个方法不能直接调用,通过类创建对象的时候系统会自动调用这个方法
init方法的作用是对对象的属性进行初始化
通过构造方法创建对象的时候,一定要保证,init方法除了self以外,其他的参数都必须有值
"""
def __init__(self, name, age):
# 在这个地方声明对象的属性
print('======')
print(name)
# 在init方法声明对象的属性
"""
name、age、sex就是Person这个类的对象属性。类的对象属性,徐娅通过对象来使用
"""
self.name = name
self.age = age
self.sex = 'Female'
# 自定义对象的打印格式
def __str__(self):
return self.name + ',' + str(self.age)
"""
对象方法默认都有一个参数self,在调用方法的时候,这个参数不用传参(系统会自动给self传参)
谁来调用这个方法,self就是谁
"""
# 声明两个对象方法,需要使用对象来调用
def eat(self):
print('Eating')
def sleep(self):
print('Sleeping, 😴')
class Student:
def __init__(self, name='Rocky', sex='Female', age=18):
self.name = name
self.sex = sex
self.age = age
def study(self, subject):
print('I need to study ' + subject + ' to improve myself !')
@classmethod
def for_future(cls):
# cls指向的是调用这个方法的类,cls可以当成类来使用
s = cls('张三')
print(s.sex)
print('good good study day day up')
@staticmethod
def for_a_better_life():
pass
class Class:
def __init__(self, name='', students=[]):
self.name = name
self.students = students
def add_student(self):
name = input('name:')
age = input('age:')
stu = Student(name, int(age))
self.students.append(stu)
class MathOperation:
@staticmethod
def add(a, b):
return a + b
@staticmethod
def sub(a, b):
return a - b
@staticmethod
def mul(a, b):
return a * b
@staticmethod
def dev(a, b):
return a / b
if __name__ == '__main__':
# print(Person.number)
# # # 构造方法中的参数实质是传给init方法的参数
# p1 = Person('Ye Hao', 18)
# print(p1)
# # print('======')
#
# Student.for_future()
# s1 = Student()
# # 获取姓名、性别、年龄
# print('方式1:')
# print(s1.name, s1.sex, s1.age)
# print('方式2:')
# print(s1.__getattribute__('name'), s1.__getattribute__('sex'), s1.__getattribute__('age'))
# print(getattr(s1, 'name'), getattr(s1, 'sex'), getattr(s1, 'age'))
# # 添加属性
# s1.__setattr__('tel', '13245678910')
# print(s1.tel)
# # 修改学生年龄
# s1.age = 22
# print(s1.age)
# # 删除学生性别
# del s1.sex
# # print(s1.sex)
# s1.study('math')
pass