python全栈开发从入门到放弃之函数进阶
1、三元运算
- a= 1
- b=2
- max = (a if a>b else b ) #条件成立的结果 if 条件 else 条件不成立的结果
- print(max)
2、先上一首python之禅
- import this
- Beautiful is better than ugly.
- Explicit is better than implicit.
- Simple is better than complex.
- Complex is better than complicated.
- Flat is better than nested.
- Sparse is better than dense.
- Readability counts.
- Special cases aren't special enough to break the rules.
- Although practicality beats purity.
- Errors should never pass silently.
- Unless explicitly silenced.
- In the face of ambiguity, refuse the temptation to guess.
- There should be one-- and preferably only one --obvious way to do it.
- Although that way may not be obvious at first unless you're Dutch.
- Now is better than never.
- Although never is often better than *right* now.
- If the implementation is hard to explain, it's a bad idea.
- If the implementation is easy to explain, it may be a good idea.
- Namespaces are one honking great idea -- let's do more of those!
Python之禅 by Tim Peters- 优美胜于丑陋(Python 以编写优美的代码为目标)
明了胜于晦涩(优美的代码应当是明了的,命名规范,风格相似)
简洁胜于复杂(优美的代码应当是简洁的,不要有复杂的内部实现)
复杂胜于凌乱(如果复杂不可避免,那代码间也不能有难懂的关系,要保持接口简洁)
扁平胜于嵌套(优美的代码应当是扁平的,不能有太多的嵌套)
间隔胜于紧凑(优美的代码有适当的间隔,不要奢望一行代码解决问题)
可读性很重要(优美的代码是可读的)
即便假借特例的实用性之名,也不可违背这些规则(这些规则至高无上)- 不要包容所有错误,除非你确定需要这样做(精准地捕获异常,不写 except:pass 风格的代码)
- 当存在多种可能,不要尝试去猜测
而是尽量找一种,最好是唯一一种明显的解决方案(如果不确定,就用穷举法)
虽然这并不容易,因为你不是 Python 之父(这里的 Dutch 是指 Guido )- 做也许好过不做,但不假思索就动手还不如不做(动手之前要细思量)
- 如果你无法向人描述你的方案,那肯定不是一个好方案;反之亦然(方案测评标准)
- 命名空间是一种绝妙的理念,我们应当多加利用(倡导与号召)
python之禅上写到命名空间是一种绝妙的理念,让我们一起多加利用吧
2、
命名空间一共分为三种:
全局命名空间
局部命名空间
内置命名空间
*内置命名空间中存放了python解释器为我们提供的名字:input,print,str,list,tuple...它们都是我们熟悉的,拿过来就可以用的方法。
三种命名空间之间的加载与取值顺序:
加载顺序:内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)
取值:
在局部调用:局部命名空间->全局命名空间->内置命名空间
- x = 1
- def f(x):
- print(x)
- print(10)
在全局调用:全局命名空间->内置命名空间
- x = 1
- def f(x):
- print(x)
- f(10)
- print(x)
- print(max)
作用域
作用域就是作用范围,按照生效范围可以分为全局作用域和局部作用域。
全局作用域:包含内置名称空间、全局名称空间,在整个文件的任意位置都能被引用、全局有效
局部作用域:局部名称空间,只能在局部范围内生效
globals和locals方法
- print(globals())
- print(locals())
- def func():
- a = 12
- b = 20
- print(locals())
- print(globals())
- func()
global关键字
- a = 10
- def func():
- global a
- a = 20
- print(a)
- func()
- print(a)
总结:
站在全局看:
使用名字:
如果全局有:用全局的
如果全局没有:用内置的
为什么要有作用域的概念:
为了函数内的变量不会影响到全局
作用域:
小范围的可以用大范围的
但是大范围的不能用小范围的
范围从大到小(图)
在小范围内,如果要用一个变量,是当前这个小范围有的,就用自己的
如果在小范围内没有,就用上一级的,上一级没有就用上上一级的,以此类推。
如果都没有,报错
函数的嵌套和作用域链
函数的嵌套调用
- def f1():
- print('f1')
- def f2():
- a = 10
- f1()
- f2()
- #代码从上到下读取,f2()调用会调用f2()函数体的内容,最后发现f1()然后调用f1()开始执行函数体的内容最后输出f1
函数的嵌套定义
函数的嵌套
为了保护内部函数,确定内部函数只能在外部函数中被调用
- def animal():
- def tiger():
- print('bark')
- print('eat')
- tiger()
- animal() #函数嵌套调用
- eat
- bark
- def f1():
- def f2():
- def f3():
- print("in f3")
- print("in f2")
- f3()
- print("in f1")
- f2()
- f1()
函数的作用域链
- ef f1():
- a = 1
- def f2():
- print(a)
- f2()
- f1()
- def f1():
- a = 1
- def f2():
- a = 2
- f2()
- print('a in f1 : ',a)
- f1()
nonlocal关键字
- def f1():
- a = 1
- def f2():
- nonlocal a
- a = 2
- f2()
- print('a in f1 : ',a)
- f1()
- #函数会使用自己本身的a的赋值,f2()函数体里面的赋值用完会从内存删除掉,想保留要加入nonlocal 加变量名才能会取f2()函数体里a的赋值
函数名的本质
函数名本质上就是函数的内存地址
1.可以被引用
- def func():
- print('func')
- print(func)
- f=func
- print(f)
- f()
- <function func at 0x000001C390B4B9D8>
- <function func at 0x000001C390B4B9D8>
- func
- #会指向函数的内存地址,不会取用函数里面的值,只有加()才能调用函数
2.可以被当作容器类型的元素
- def func():
- print('func')
- print(func)
- f=func
- print(f)
- l = [f]
- print(l)
- l[0] == f
- l[0]()
- <function func at 0x0000025B3C73B9D8>
- <function func at 0x0000025B3C73B9D8>
- [<function func at 0x0000025B3C73B9D8>]
- func
3.可以当作函数的参数和返回值
- 第一类对象(first-class object)指
- 1.可在运行期创建
- 2.可用作函数参数或返回值
- 3.可存入变量的实体。
*不明白?那就记住一句话,就当普通变量用
闭包
1.闭 内部的函数
2.包 包含了对外部函数作用域中变量的引用
闭包的常用形式
- def hei():
- x = 20
- def inner():
- print(x) #局部的
- return inner
闭包函数:
内部函数包含对外部作用域而非全剧作用域名字的引用,该内部函数称为闭包函数
函数内部定义的函数称为内部函数
由于有了作用域的关系,我们就不能拿到函数内部的变量和函数了。如果我们就是想拿怎么办呢?返回呀!
我们都知道函数内的变量我们要想在函数外部用,可以直接返回这个变量,那么如果我们想在函数外部调用函数内部的函数呢?
是不是直接就把这个函数的名字返回就好了?
这才是闭包函数最常用的用法
- def func():
- name = 'eva'
- def inner():
- print(name)
- return inner
- f = func()
- f()
判断闭包函数的方法.__closure__
- def func():
- name = 'eva'
- def inner():
- print(name)
- print(inner.__closure__)
- return inner()
- 7 func() #看输出是否有cell元素有就是闭包函数
- (<cell at 0x000002711EE465B8: str object at 0x000002711EEDA500>,)
- eva
- #输出的__closure__为None :不是闭包函数
- name = 'egon'
- def func2():
- def inner():
- print(name)
- print(inner.__closure__)
- return inner
- f2 = func2()
- f2()
- None
- egon
闭包函数的嵌套
- def wrapper():
- money = 1000
- def func():
- name = 'eva'
- def inner():
- print(name,money)
- return inner
- return func
- f = wrapper()
- i = f()
- i()
闭包函数在网络上的应用
- from urllib.request import urlopen
- def index():
- url = "http://www.xiaohua100.cn/index.html"
- def get():
- return urlopen(url).read()
- return get
- xiaohua = index()
- content = xiaohua()
- print(content)
本次小结:
命名空间:
一共有三种命名空间从大范围到小范围的顺序:内置命名空间、全局命名空间、局部命名空间
作用域(包括函数的作用域链):
调用时,如果在自己的空间内有,就用自己的。如果没有就使用大范围的。不能从大范围中用小范围的。
函数的嵌套:
嵌套调用
嵌套定义:定义在内部的函数无法直接在全局被调用
函数名的本质:
就是一个变量,保存了函数所在的内存地址
闭包:
内部函数包含对外部作用域而非全剧作用域名字的引用,该内部函数称为闭包函数
python全栈开发从入门到放弃之函数进阶的更多相关文章
- python全栈开发从入门到放弃之函数基础
1.为什么要用函数#1.避免代码重用#2.提高代码的可读性 2.函数的定义def 函数名(参数1,参数2): '''函数注释''' print("函数体") re ...
- python全栈开发从入门到放弃之迭代器生成器
1.python中的for循环 l = [1,2,3,4,5,6] for i in l: #根据索引取值 print(i) 输出结果: 1 2 3 4 5 6 2.iterable 可迭代的 可迭 ...
- python全栈开发从入门到放弃之socket网络编程基础
网络编程基础 一 客户端/服务器架构 1.硬件C/S架构(打印机) 2.软件C/S架构 互联网中处处是C/S架构 如黄色网站是服务端,你的浏览器是客户端(B/S架构也是C/S架构的一种) 腾讯作为服务 ...
- python全栈开发从入门到放弃之递归函数的调用
1.递归效率低,需要在进入下一次递归时保留当前的状态,见51cto博客 解决方法是尾递归,即在函数的最后一步(而非最后一行)调用自动但是python又没有尾递归,且对递归层级做了限制 必须有一个明确的 ...
- python全栈开发从入门到放弃之初识面向对象
面向过程 VS 面向对象 面向过程的程序设计的核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西. 优点是:极大的降低了写程序的复 ...
- python全栈开发从入门到放弃之面向对象的三大特性
组合 class Course: def __init__(self,name,period,price): self.name = name self.period = period self.pr ...
- python全栈开发从入门到放弃之socket并发编程多进程
1.1 multiprocessing模块介绍 python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大部分情况需要使用多进程 ...
- python全栈开发从入门到放弃之socket并发编程多线程
一 threading模块介绍 multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性,因而不再详细介绍 二 开启线程的两种方式 from threadi ...
- python全栈开发从入门到放弃之socket并发编程之协程
一.为什么会有协程 本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质:切换+保存状态 cpu正在运行一个任务,会在两种情 ...
随机推荐
- 第二百五十一节,Bootstrap项目实战--响应式轮播图
Bootstrap项目实战--响应式轮播图 学习要点: 1.响应式轮播图 本节课我们要在导航条的下方做一张轮播图,自动播放最新的重要动态. 一.响应式轮播图 响应式轮播图 第一步,设置轮播器区域car ...
- C++之拷贝构造函数、深拷贝、浅拷贝
C++ Code 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 ...
- shell脚本学习总结10--系统函数调用
1.打印出彩色的格式 [root@new sbin]# cat demo.sh #/bin/bash . /etc/init.d/functions read -p "Pleas input ...
- M451定时器的寄存器讲解
M451的定时器的寄存器的这一章节,相信很多人都清楚明白了,但还是有必要说一说的 /** * @brief Timer0 IRQ * * @param None * * @return None * ...
- Spring学习笔记--使用Spring基于Java的配置
我们需要使用@Component注解来定义一个配置类,在配置类中我们定义Bean: package com.moonlit.myspring; import org.springframework.c ...
- Android 全局异常处理(二)
CrashHandler package org.wp.activity; import java.io.File; import java.io.FileOutputStream; import ...
- Struts 入门(一) 搭建Struts环境
eclipse中创建项目 搭建步骤: 1.创建web项目 2.下载导入相关jar包 3.创建并完善相关配置文件 4.创建(控制器)Action 并测试启动 1.文件--新建--动态web项目 给项目起 ...
- [Android Tips] 26. Multiple Maven repositories in Gradle
来自 https://gradleproject.wordpress.com/2013/02/14/multiple-maven-repositories-in-gradle/ This DOESN' ...
- 160422、Highcharts后台获取数据
而我这次做的是趋势图,涉及到动态刷新,做的过程还是花了一番功夫的,也补充和巩固了一点js的知识,为了纪念,把过程记录一下: 首先,是引入HIghcharts绘图相关的js文件和jQuery.js. 接 ...
- SharePoint Managed Metadata 使用总结
前言 本文完全原创,转载请说明出处,希望对大家有用. 在SharePoint开发中,通常我们会将数据存储在列表,文档库或者直接存到数据库.但涉及到数据的层级结构时,用列表等存储实现并不是一件简单的事情 ...