11、python高阶编程&面向对象(上)——旺仔

在这里插入图片描述

一、高级编程

1、 列表推导式

  推导式分为 列表推导式、字典推导式、集合推导式等。在这里我们主要说其中一种也是用的最多列表推导式。
  列表推导式是Python构建列表(list)的一种快捷方式,可以使用简洁的代码就创建出一个列表简单理解就是由一个旧的列表来构建出一个新的列表。
  总的来说,列表推导式就是将好几行代码简化,使代码更简洁,之后我们将详细讲一下列表推导式的几种语法。

语法一:

 [表达式 for 变量 in range]

  此方法可以使用range来创建所需的数值列表,例如实例中创建含有10个元,并且素都是1~10之间的随机数值的列表

  • 实例:
    我们用for循环遍历与列表推导式来比较一下
# for循环遍历
import random
list1 = []
for i in range(10):
    list1.append(random.randint(1,10))
print(list1)

运行结果 》》》
[8, 3, 4, 7, 1, 10, 3, 7, 3, 4]
# 列表推导式
import random
list1 = [random.randint(1,10) for i in range(10)]
print(list1)

运行结果 》》》
[1, 3, 7, 8, 7, 2, 9, 4, 2, 10]

可以很直观的看到,使用列表推导式比for循环遍历少了2行代码,但是效果却是相同。

语法二:

  此语法可以满足一些需求,比如对旧列表中的每一个元素都进行相同的操作。

[表达式 for 变量 in 旧列表]
  • 实例:
# for循环遍历
list1 = ['cheney', 'tony', 'jerry', 'amy']
list2 = []
for i in list1:
    list2.append(i + '老师新年好')
print(list2)

运行结果 》》》
['cheney老师新年好', 'tony老师新年好', 'jerry老师新年好', 'amy老师新年好']
# 列表推导式
list1 = ['cheney', 'tony', 'jerry', 'amy']
list2 = [i + '老师新年好' for i in list1]
print(list2)

运行结果 》》》
['cheney老师新年好', 'tony老师新年好', 'jerry老师新年好', 'amy老师新年好']

这里我们依旧可以看到列表推导式的简便,但是咱不能小看就这么小小的少了2行代码,当代码量大的时候,还是会显得尤为重要。

语法三:

  此语法能进行一些条件判断的需求

[表达式 for 变量 in 旧列表 if 条件]
  • 实例:只想保留列表中不大于4的数的平方
# for循环遍历
list1 = [2, 4, 1, 7, 3, 5, 6]
list2 = []
for i in list1:
    if i <= 4:
        i **= 2
        list2.append(i)
print(list2)

运行结果 》》》
[4, 16, 1, 9]
# 列表推导式
list1 = [2, 4, 1, 7, 3, 5, 6]
list2 = [i**2 for i in list1 if i <= 4]
print(list2)

运行结果 》》》
[4, 16, 1, 9]

  这里我们就能看到,加上判断条件,如果还用以前的遍历,用了7行代码,但是列表推导式还是3行。
  当然,列表推导式还有很多其他的用法,比如与lambda函数结合使用,或者是判断其他条件等等,这里就不过多介绍了,后面讲到的生成器与迭代器也会用到列表推导式,也可以了解一下,欢迎各位猿友一起共同讨论学习。

2、生成器

  当一个序列或者元祖中的数据特别大,但是我们又不需要同时使用这些数据,如果一次性把数据读到内存中,那么对计算机内存是一个很大的浪费,甚至可能会把内存撑爆了,python中有这样的一个数据结构,就是将我们需要的数据通过循环不断返回后续的元素,而不是一次性打开全部元素,从而节省大量的内存空间,这种机制就是 generator 生成器
  生成器的特征:生成一个生成器,一旦数据取完了,那么数据就不存在了

方式一:推导式的方式

  • 语法:
generator = (表达式 for 变量 in 列表 if 表达式)

看到这个语法的时候是不是感觉与列表推导式又一些相似?对,你没看错,就是将中括号【】换成括号()

  • 实例:

我们先看一个简单的推导,生成1~10中的数字的三倍

list1 = (x * 3 for x in range(1, 11))

print(list1, type(list1))
运行结果 》》》
<generator object <genexpr> at 0x000001E7C0019830> <class 'generator'>

print(list1.__next__())
运行结果 》》》
3

print(list1.__next__())
运行结果 》》》
6

print(list1.__next__())
运行结果 》》》
9

print(next(list1))
运行结果 》》》
12

  我们可以看到,每次使用__next__()方法然后输出都会得到一个结果,__next__()方法也可以写成next()函数,就像实例中的最后一个。


列表推导式语法3中的实例写成生成器

list1 = [2, 4, 1, 7, 3, 5, 6]
list2 = (i**2 for i in list1 if i <= 4)

print(list2.__next__())
运行结果 》》》
4

print(list2.__next__())
运行结果 》》》
16

print(list2.__next__())
运行结果 》》》
1

print(list2.__next__())
运行结果 》》》
9

print(list2.__next__())
运行结果 》》》
StopIteration

  这里肯定有人疑惑前四次运行都能得到值,为什么第5次就会报错,然后出现StopIteration(停止迭代)
  这里就是__next__()方法的一个特点,每一次使用__next__()方法都会去掉一个值,当没有值可取的时候就会停止迭代,而且每一次都是从第一位开始取,取完就将值去掉,所以才会出现上述情况,但是一般使用生成器都是在值非常大的时候,所以这个问题一般不会出现

方式二:生成器函数

  • 语法:
def fun():
    i = 0
    while True:
        i += 1
        yield i


r = fun()
print(r)
运行结果 》》》
<generator object fun at 0x00000227629A9830>

print(next(r))
运行结果 》》》
1

print(next(r))
运行结果 》》》
2

  yield在第八讲的博客中斐波那契数列已经使用过了,但是没有讲解他到底是怎么运行的,此处讲带大家取了解其用法。
  yield与return有些相似,都可以终止程序的运行,但是yield还能续上,return就不行。
  加上yield的函数就会变成生成器了,这里我们在输出r得到的结果就可以看到,generator object fun就已经能说明他变成了一个生成器对象
  第一次使用__next__()方法输出结果1后,程序会被终止在第4行结束,而且1输出后,这个1就已经被销毁了,下一个__next__()方法出现后就会再次输出结果,之后还是终止在第4行结束。
  让我们在来看一个实例更清晰的了解生成器函数。

  • 实例
def fun():
    for i in range(10):
        yield i


r = fun()
print(r)
运行结果 》》》
<generator object fun at 0x0000019087F49830>

list1 = [i for i in r]
print(list1)
运行结果 》》》
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

list2 = [i for i in r]
print(list2)
运行结果 》》》
[]

  在list1使用列表推导式获得生成器函数中生成的值后,我们发现再给list2赋值时,我们得到了一个空列表。
  我们需要知道一个点,列表推导式中自带了__next__()方法,然而 __next__()方法每次用到都会将一个值取出,然后去掉,所以在使用完用列表推导式取完生成器函数的值后就不会再有值,所以再使用就不会得到任何值。当然肯定也不会有StopIteration(停止迭代)的报错

  • 生成器求前20个斐波那契数列讲解
def fun2(n):
  a, b = 0, 1
  for i in range(0, n):
    a, b = b, a + b
    yield a


list1 = [i for i in fun2(20)]
print(list1)
运行结果 》》》
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765]
运行过程:
n=20 a=0 b=1  开始
i=0 a=1 b=1
i=1 a=1 b=2
i=2 a=2 b=3
i=3 a=3 b=5
i=4 a=5 b=8
i=5 a=8 b=13
i=6 a=13 b=21
i=7 a=21 b=34
i=8 a=34 b=55
i=9 a=55 b=89
i=10 a=89 b=144
i=11 a=144 b=233
i=12 a=233 b=377
i=13 a=377 b=610
i=14 a=610 b=987
i=15 a=987 b=1597
i=16 a=1597 b=2584
i=17 a=2584 b=4181
i=18 a=4181 b=6765
i=19 a=6765 b=10946

  详细的运行结果如上,每一次yield都会暂时中断一次,使用列表推导式结合,把生成器每次的值都那出来给列表,最终达成需求,相信看懂了整个运行过程后,生成器函数也并不是很难。

3、迭代器

  生成器就是一种特殊的迭代器,并且迭代器的注意事项都与生成器差不多,所以在掌握了生成器之后,迭代器就十分简单了。

  • 注意:
    迭代器会记住上次停留的位置
    迭代器一旦数据取完,那么你继续用next()来取数据会直接报错
    迭代器的数据只能取一次,取完一次之后迭代器就不能继续使用了

得分清楚可迭代对象的方法__iter__()迭代器的方法:__iter__()和__next__()
__iter__()方法是取其自身,__next__()方法是取下一个元素
在这里插入图片描述

创建方法:

list1 = [1, 2, 3, 4, 5]
iterator = iter(list1)

迭代器与列表推导式:

list1 = [1, 2, 3, 4, 5]
iterator = iter(list1)
print(type(iterator), iterator)
运行结果 》》》
<class 'list_iterator'> <list_iterator object at 0x00000202F8785828>

list2 = [i for i in iterator]
print(list2)
运行结果 》》》
[1, 2, 3, 4, 5]

list3 = [i for i in iterator]
print(list3)
运行结果 》》》
[]

  看到这里,您是否对生成器迭代器有了一丝了解呢,旺仔之前看了一篇文章,他的博客对此讲的特别细,看的直呼大佬,然后感觉自愧不如,感兴趣的猿友可以去看一下,时刻向大佬学习。博客链接

二、面向对象(上)

名词解释:
  对象,指行动或思考时作为目标的事物或特指恋爱的对方等含义。我国学者唐震在《接受与选择》一书中把对象看成是围绕着人的、被人用来接受或选择的特定事物。他提出了对象序列说:个体的对象世界是指从个体诞生开始就围绕在个体周围的世界,它包括支持该个体存在的物质实体和用于该个体发展的各种因素。从个体的生存处境看,个体的对象世界是我们通常所指的广泛意义上的自然界以及这个自然界的展开形式。这个世界由低级到高级依次展开,它们呈现给个体的是由“原始自然——人化自然——能动自然——虚拟自然”等所构成的序列。
  有一句话讲的特别好,万物皆对象

1、面向对象简介

  • Python是一门面向对象的编程语言

  面向对象编程是一种编程方式,此编程方式的落地需要使用 “类” 和 “对象” 来实现,所以,面向对象编程其实就是对 “类” 和 “对象” 的使用。简单理解就是语言中的所有操作都是通过对象来进行的。

  • 类就是一个模板,模板里可以包含多个函数,函数里实现一些功能
  • 对象则是根据模板创建的实例,通过实例对象可以执行类中的函数
  • 面向过程

根据需求逻辑从上到下写垒代码
面向过程指将我们的程序分解为一个一个步骤,通过对每个步骤的抽象来完成程序
这种编写方式往往只适用于一个功能,如果要实现别的功能,往往复用性比较低
这种编程方式符号人类的思维,编写起来比较容易
比如在现实生活中,我要想做一件事,我就得做计划,包括我们做的每一件事都是过程。

  • 面向对象的编程语言,关注的是对象,而不注重过程,对于面向对象一切皆对象

  面向对象不关注过程,比如我让室友去给我带个饭,室友要穿衣服,穿鞋,拿手机,走去食堂,找到摊位,购买餐品,付钱,走路回来,把饭给我。室友的这一切行为都是过程,而我拿到饭就是我所需的对象,也就是结果,面向对象就好比我根本不关注室友怎么走,穿什么衣服,什么鞋子,只关注带回来的饭这个结果。

  为什么要讲这些呢,因为python中的道理也与上述举例一样,既别人创建了对象,如class,我根本就不用管它里面怎么编写,怎么实现功能,我只要能拿来使用既可,不然每当想要一个效果都得自己从底层慢慢开始编写,既耗时又耗力,很不划算。就跟以前高中用的数学公式物理公式什么的,我们根本不用管他们到底是怎么研究出来的,只要好用,能节约大量时间就行。

2、类(class)

  我们上面了解了什么是面向对象,也就是我们使用别人创建的对象,接下来我们就要开始自己创建对象,从类开始,我们将掌握如何自己创建,最终封装一些自己写的一些代码。

2.1、类的简介

我们在之前已经接触过许多类,比如我们的str,但是可能搞不清楚类与对象的区别

str()
a = 'abc'
print(type(a))
运行结果 》》》 
<class 'str'>	
# 比如使用split的方法,是如下使用
# 对对象'abc'进行操作,不是对str()类进行操作
str()
print('abc'.split('b'))

2.2、类的创建和实例对象的生成

  • 语法(对象的创建):
    类的名称在自定义的时候必须使用大驼峰命名法。

  用Cheney老师的话来说,类就相当于车的图纸,然后拿着图纸去创建车(对象)。这种对象称之为一类对象,就相当于一款汽车。

# MyClass 是类的名称  MyClass()是类的实例化 创建类的对象
class MyClass():
    pass


print(MyClass)
运行结果 》》》 
<class '__main__.MyClass'>

mc = MyClass()    # 创建对象也称呼为类的实例化
print(mc, type(mc))
运行结果 》》》 
<__main__.MyClass object at 0x000001DAC2C357B8> <class '__main__.MyClass'>

  0x000001DAC2C357B8就是我们创建的对象的地址,只要是对象就一定会在内存中开辟一个地址。当然我们再写一个mc1 = MyClass(),这就又是一个新的地址,也就是另一个对象,通俗一点讲,就算拿相同图纸(类)去创建车子(对象),车(对象)也肯定不会一样。

  • 检测对象是不是此类的对象

  使用isinstance检测一个对象是不是这个类的对象,在以后我们可能会写很多的类,也会创建很多对象,可能自己都不知道哪个对象是哪个类的,所以检测显得尤为重要。是则返回True,不是则返回Flase

# 接上述实例
r = isinstance(mc, MyClass)
print(r)
运行结果 》》》 
True

2.3、类的使用

python中万物皆对象,所以类也是一个对象喔!!

class MyClass():
    pass


print(id(MyClass), type(MyClass))
运行结果 》》》 
1571347124712 <class 'type'>

可以发现我们创建的类MyClass是type来管理的,而且它也是一个对象

  • 使用类创建方法
class Person():
  name = '旺仔1'  # 数据  (属性)

  def like(w):  # 能做什么事情 行为  (方法)
    print('python')


p1 = Person()     
p2 = Person()

p1.name = '旺仔2'  # 这是给实例对象添加属性的方式
print(p1.name)
print(p2.name)

p1.like()  # 方法的使用
运行结果 》》》 
旺仔2
旺仔1
python

直接看这个可能不太好理解,让我们看一个简单的。

a = 'python1'
print(a.split('1'))
运行结果 》》》
['python', '']

这里我们就用到了str的类,给a赋值的时候等于创建了一个对象(实例),然后用split方法对实例进行操作,我们自己创建的方法就跟这个差不多。例如我们上面创建了一个like的方法,然后我们就可以使用这个方法。

在这里插入图片描述

旺仔注:

很久都没有更新博客了,因为过年嘛,玩了好长时间,不过也想了很多事情,既然选择了某个方向,就要一直走下去,还有很多人根本没有选择的机会,所以还是不能一直贪玩,还是那句话,努力不一定有结果,但是不努力就一定会失败,人生没有回头路,为了美好的明天,继续奋斗吧,不能在懒惰下去了!!在这里插入图片描述

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值