从零开始的python数据分析(二)

python中的类

简单来说,类就是对某一类事物的描述,它是抽象的、概念上的定义。而对象是实际存在的该类事物中的个体。一个类中可以定义多个对象,但每个对象都是一个独立的存在,如果修改其中一个对象的属性,其他对象是不会受到影响的(全局共享的静态成员除外)。这就体现了面向对象的一个重要特性—封装性。

类的定义和使用

Python使用关键字class来定义一个新类,class关键字之后是一个空格,接下来是类名,然后以冒号(:)结尾,类体部分要具有相同的缩进,标识归属于这个类,当通过对象调用方法时,对象本身(即self)将作为第一个参数被传递过去,而普通函数则不具备这个特性。`

class Student:
    Sname=""
    Sno=0
    def __init__(self,name,no):
        self.Sname=name
        self.Sno=no
    def prt(self):
        print("%s is %d"%(self.Sname,self.Sno))

s1=Student('dzj',1)
s1.prt()

在Python中,以下画线开头或结尾的成员通常都有特殊的含义。比如,有如下三种情况值得注意(下面的“xxx”表示任意合法的字符串)。

_xxx:以一个下画线开始的成员,表示保护成员,凡是被这样标识命名的都不能通过“from module import *”的方式导入。也就是说,这类保护成员只对自己和其子类开放访问权限。

xxx:前后都有两个下画线的成员,表示Python系统自定义的特殊成员。比如,init()表示构造方法,del()表示析构方法等。

__xxx:仅前面由两个下画线开始的成员,表示私有成员(如前所述)。这类成员只能供类内部使用,不能被继承,但可以通过“对象名._类名__xxx”这样特殊的方式来访问。因此,严格意义上,Python中不存在私有成员。

类的继承

在面向对象程序设计中,继承(Inheritance)是软件复用的关键技术。通过继承,子类可以复用父类的优秀特性,同时还可进一步扩充新的特性,适应新的需求。在已有类的基础上新增自己的特性,继而产生新类的过程,称为派生。我们把既有的类称为基类(Base Class),而将派生出的新类称为派生类(Derived Class)或子类(Subclass)。

子类不继承父类的私有方法,但是可以调用父类的函数来实现定义等操作

如果父类方法的功能不能满足子类的需求,那么可在子类中重写父类的方法,这种改造父类同名方法的策略,称为覆写(Override)。

生成器

通过推导式,我们可以直接创建一个列表、字典或集合。但是,由于受到内存的限制,这些可迭代对象(列表、字典或集合)的容量是有限的。比如,创建一个包含10万个元素的列表,不仅要占用很大的存储空间,而且根据局部性原理,在一段时间内我们要访问的仅仅局限于相邻的若干个元素,即使把所有元素都加载到内存之中,它们被“临幸”的概率也非常小。因此,大部分的存储空间其实是被白白浪费了。

基于此,我们就会有这样的需求:这些元素能不能按照某种算法推算出来,然后在后续循环过程中,根据这些元素不断推算出其他被访问的元素呢?这样一来,就不必创建完整的列表、字典或集合了,从而节省了大量的空间。在Python语言中,这种一边循环一边计算的机制,称为生成器。

生成器的定义

使用列表推导式来定义生成器

创建一个生成器并不复杂,方法也有很多。最简单的一种方法莫过于把一个列表推导式最外层的标记方括号[]改成圆括号()。

a=[x**2 for x in range(10) if x%2==0] #列表推导式
b=(x**2 for x in range(10)if x%2==0)  #生成器

得到推导式后可以调用next函数来获得生成器的返回值

b=(x**2 for x in range(10)if x%2==0)
print(next(b))        #0
print(next(b))        #4

使用yield关键字来定义生成器

如果某个函数定义中包含yield关键字,那么这个函数就不一般了,它不再是一个普通函数,而是一个生成器。

它的返回值不再是执行到最后一行就返回,而是执行到yield语句处,再次执行时,会从上次执行的yield语句开始执行。

def f(k):
    n,a,b=0,0,1
    while n<k:
        yield b
        a,b=b,a+b
        n=n+1
func=f(10)
next(func)       #1
next(func)       #1
next(func)       #2

当生成器中的元素过多时,可以通过for循环来遍历所有元素

for i in f(10):
    print(i,end=' ')
    #1 1 2 3 5 8 13 21 34 55

生成器的执行流程

在本质上,生成器就是一种元素生成函数,它和普通函数的不同之处在于,它的返回值不是通过return返回的,而是通过yield返回的。

def f():
    print('1')
    yield(1)
    print('2')
    yield(2)
    print('3')

func=f()
next(func)     #1
next(func)     #2
next(func)     #3

迭代器

可迭代对象

在Python中,有很多好用的数据类型,如列表、元组、字典、集合、字符串等。事实上,这些所谓的“数据类型”,更确切地说是存储数据的容器(container)。操作这些容器时,我们常需要逐个访问其中的元素。这种逐个获取容器中元素的过程,就叫“迭代”(iteration)。简单来说,具备可迭代访问特性的对象,就叫作可迭代对象。

迭代器的建立

在Python中,一切皆对象。迭代器也不例外,具体的迭代器实际上是某个迭代类定义的对象。比如list_iterator是列表类迭代器的对象,set_iterator是集合类迭代器的对象,以此类推。

所有的迭代器在设计之时通常都会在类中实现两个方法:iter()和__next__()。iter()方法用于返回一个迭代器对象,next()方法用于返回迭代对象内部的下一个元素值。

每次调用next()方法的时候,next()会在背后默默做如下两件事。
1、为下一次调用next()方法修改状态。
2、为当前调用生成返回结果。

class Fibonacci(object):
    """斐波那契数列得迭代器"""
    def __init__(self,nums):
        self.nums = nums   # 传入参数,生成斐波那契数列的个数
        self.a = 0   
        self.b = 1
        self.i =0    # 用于记忆生成的个数
    def __iter__(self):
        return self
 
    def __next__(self):
           
       ret = self.a   # 记忆第一个数
 
       if self.i < self.nums:
            self.a, self.b = self.b,self.a +self.b
            self.i += 1
            return ret
       else:
           raise StopIteration   # 停止迭代
 
nums = int(input("请输入需要生成Fibonacci数列项的个数:"))
fobo = Fibonacci(nums)
 
for num in fobo:
    print(num)

使用islice函数创建迭代器

该函数的第一个参数就是一个可迭代对象,随后的参数分别是迭代对象的起始位、终止位和步长。它的用法和列表及元组的“切片”函数非常类似。事实上,islice就是“迭代分片”的意思,其中“i”表示“iterable”(可迭代对象),“slice”表示“分片”。但是,这个迭代切片不支持负数索引。

from itertools import islice 
class F:
    def __init__(self):
        self.pre,self.cur=0,1
    def __iter__(self):
        return self
    def __next__(self):
        val=self.cur
        self.pre,self.cur=self.cur,self.cur+self.pre
        return val
f=F()
a=list(islice(f,0,10))
print(a)

简单来说,迭代器就像一个惰性加载的工厂,等到有人需要时,它才加工产品,返回生成值,当没人搭理的时候,它就处于休眠状态,等待下一次调用来唤醒。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值