python怎么定义a_python一些基础知识2
四.模块,包,标准模板
1..py文件-模块
一个.py文件就称之为一个模块,Module,模块使用的最大好处是大大提高了代码的可维护性。当然,还提高了代码的复用性。使用模块还可以避免函数名和变量名冲突,相同名字的变量完全可以分别存在不同的模块中。但是也要注意,变量的名字尽量不要与内置函数名字冲突。
2.包
当编写的模块多了,模块的名字重复的概率就增加了。如何解决这个问题呢?
Python引入了按目录来组织模块,称为包,Package,比如:
extensions
├─ __init__.py
├─ dog.py
└─ cat.py
现在 dog.py模块的名字就变成了extensions.dog, 请注意,每一个package目录下面都会有一个__init__.py 的文件,这个文件是必须有的,否则,Python就把这个目录当成普通目录,而不是一个package directory。
3.使用包中的Module
编写一个dog.py模块:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
' a test module '
__author__ = 'jack guo'
import sys
def shout():
args = sys.argv
if len(args)==1:
print('Hello, I'm afei, welcome to world!')
elif len(args)==2:
print('Hello, %s!' % args[1])
else:
print('Yes,sir')
if __name__=='__main__':
shout()
第1行注释可以让dog.py文件直接在linux上运行;
第2行注释表示.py文件本身使用标准UTF-8编码;
第4行表示模块的文档注释;
第6行表示模块的作者; 注意最后两行代码,当我们调试dog.py时,shout()会调用,当在其他模块导入dog.py时,shout()不执行。
3.模块的一种标准模板
以上代码中的前六行:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
' a test module '
__author__ = 'jack guo'
#以上是模块的标准模板
五.闭包
1.返回函数
函数名是变量名,那么自然可以作为函数的返回值返回。
def lazy_sum(mylist):
def sum():
return reduce(lambda x, y: x + y, mylist)
return sum
如上所示,lazy_sum函数返回一个函数,其名字叫做sum,它如何使用呢?
mysum = lazy_sum([1,3,5,7])
print(mysum)
#.sum at 0x7f42c4166c80>
lazy_sum的返回函数赋值给mysum,当我们打印mysum时发现,并没有真正运行内部包裹的函数sum,而是返回一个sum的地址值,因此这是一种延迟加载。
so,调用 mysum() 结果:16
这才真正运行了内部函数sum
一般的函数,比如:
def sum2():
return reduce(lambda x, y: x + y, mylist)
我们直接调用 rslt = sum2([1,3,5,7]),直接拿到结果了。
注意,lazy_sum(mylist)的参数为mylist,而位于它内部的函数sum()是没有参数的,但是sum()函数在内部却可以引用外部函数的参数 mylist。
2.闭包
当函数lazy_sum返回了一个函数sum后,外部函数lazy_sum的变量还被内部函数或返回的新函数sum引用,这被称为闭包。
一般地,函数内部的临时变量或参数只能被它自己所用,不可能被其他函数引用。
但是,闭包时,返回的内部函数却可以引用其外部的函数中的临时变量和参数。
3.闭包例子
"""
lazy sum
"""
def lazy_sum2(mylist):
tmp=10
def sum():
return reduce(lambda x, y: x + y, mylist)
return sum,tmp
sumfun,tmp = lazy_sum2([1,3,5,7])
print(sumfun())
#16
print(tmp)
#10
可以看到lazy_sum2函数内的tmp临时变量可以被内部函数sum引用
总结:闭包具有延迟加载特性,返回的函数可以引用其外部函数的局部变量和参数。
4.闭包与装饰器
python中的闭包从表现形式上定义(解释)为:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)。
所谓装饰器就是在闭包的基础上传递了一个函数,然后覆盖原来函数的执行入口,以后调用这个函数的时候,就可以额外实现一些功能了。装饰器的存在主要是为了不修改原函数的代码,也不修改其他调用这个函数的代码,就能实现功能的拓展。
闭包例子:
def f1():
x = 1
def f2():
print(x)
return f2
f=f1()
print(f)
x=100
f()
print(x)
结果:
.f2 at 0x0000013C5F5147B8>
1
100
闭包应用:
from urllib.request import urlopen
def index(url):
def get():
return urlopen(url).read()
return get
oldboy=index('http://crm.oldboyedu.com')
print(oldboy().decode('utf-8'))
装饰器例子:
装饰器的功能是将被装饰的函数当作参数传递给与装饰器对应的函数(名称相同的函数),并返回包装后的被装饰的函数”
直接看示意图,其中 a 为与装饰器 @a 对应的函数, b 为装饰器修饰的函数,装饰器@a的作用是:
简而言之:@a 就是将 b 传递给 a(),并返回新的 b = a(b)
def a(name):#与装饰器对应的函数
return name()
@a #装饰器 b = a(b)
def b(): #被装饰函数
print('hello')
输出
hello
注意##:
解析过程是这样子的:
1.python 解释器发现@a,就去调用与其对应的函数( a 函数)
2.a 函数调用前要指定一个参数,传入的就是@a下面修饰的函数,也就是 b()
3.a() 函数执行,调用 b(),b() 打印"hello”
装饰器应用例子:
import time
def timmer(func):
def wrapper():
start_time=time.time()
func()
stop_time=time.time()
print('run time is %s' %(stop_time-start_time))
return wrapper
@timmer
def index():
time.sleep(1)
print('welcome to index')
index()
输出:
welcome to index
run time is 1.0000543594360352
装饰器框架:
def timer(func):
def wrapper(*args,**kwargs):
func(*args,**kwargs)
return wrapper
5.作用域
命名空间的可见性就是作用域1. 全局作用域:内置名称空间,全局名称空间
2. 局部作用域:局部名称空间
名字的查找顺序:局部名称空间---》全局名层空间---》内置名称空间
查看全局作用域内的名字:gloabls()
查看局部作用域内的名字:locals()
全局作用域的名字:全局有效,在任何位置都能被访问到,除非del删掉,否则会一直存活到文件执行完毕。
局部作用域的名字:局部有效,只能在局部范围调用,只在函数调用时才有效,调用结束就失效。
六.继承,多态,鸭子类型
1.继承
#编写一个类
class Animal(object):
def shout(self):
print('Animal is shouting...')
#继承Animal的Dog:
class Dog(Animal):
def shout(self):
print('Dog is shouting...')
#继承Animal的Cat:
class Cat(Animal):
pass
2.多继承(MixIn设计原则)
Java和C#等不允许多继承类,但是Python是可以的。
通过多重继承,一个子类就可以同时获得多个父类的所有功能。
在设计类的继承关系时,通常,主线都是单一继承下来的,例如,Dog继承自Animal。
但是,如果需要定制个性化的功能,通过多重继承就可以实现,比如,让Dog除了继承自Animal外,再同时继承Runnable类,这种设计理念称为MaxxIn原则。
3.多态
多态指的是一类事物有多种形态,(一个抽象类有多个子类,因而多态的概念依赖于继承)。
序列类型有多种形态:字符串,列表,元组。
动物有多种形态:人,狗,猪
多态性是指具有不同功能的函数可以使用相同的函数名,这样就可以用一个函数名调用不同功能的函数。
比如:老师.下课铃响了(),学生.下课铃响了(),老师执行的是下班操作,学生执行的是放学操作,虽然二者消息一样,但是执行的效果不同。静态多态性:如任何类型都可以用运算符+进行运算
动态多态性:
多态性是‘一个接口(函数func),多种实现(如f.click())’
dog = Dog()
dog.shout()
#结果:
Dog is shouting...
当子类和父类都存在相同的shout()方法时,子类的shout()覆盖了父类的shout(),在代码运行的时候,总是会调用子类的shout()。这样就获得了继承的另一个好处:多态。
4.鸭子类型
class Car(object):
def shout(self):
print('Car is shouting...')
静态语言,如Java,如果需要传入Animal类型,则传入的对象必须是Animal类型或者它的子类Dog或Cat,如果传入Car实例,将无法调用shout()方法。
对于Python这样的动态语言来说,则不一定需要传入Animal类型,只需要保证传入的对象有一个shout()方法就可以了,传入Car实例不报错。这种,“file-like object“就是一种鸭子类型。
七.获取对象的类型,方法,setattr()添加属性
1.基本类型
基本类型都可以用type()判断:
type(123)
type('str')
2.指向函数或类的变量
#也可以用type()判断:
a = Animal()
type(a)
type(abs)
#如果函数不是内置函数,该怎么查看变量是否是函数类型?
3.变量指向非内置函数
借助types模块
import types
def fn():
... pass
...
type(fn)==types.FunctionType
True
type(lambda x: x)==types.LambdaType
True
type((x for x in range(10)))==types.GeneratorType
True
4.IsInstance判断实例的类型
object
|
|--- Animal
|
|--- Dog
|
|--- Cat
robertCat = Cat()
isinstance(robertCat , Cat)
True
isinstance(h, Animal)
True
5.使用dir()
如果要获得一个对象的所有属性和方法,可以使用dir()函数,它返回一个包含字符串的list,比如,获得一个str对象的所有属性和方法:
dir('edc')
['__add__', '__class__',..., '__subclasshook__', 'capitalize', 'casefold',..., 'zfill']
6.getattr()
仅仅把属性和方法列出来是不够的,配合getattr()、setattr()以及hasattr(),我们可以直接操作一个对象的状态。
hasattr(obj, 'power') # 有属性'power'吗?
True
getattr(obj, 'power') # 获取属性'power'
>
7.setattr()
class MyObject(object):
def __init__(self):
self.x = 123
obj = MyObject()
hasattr(obj, 'x') # 有属性'x'吗?
True
obj.x
123
hasattr(obj, 'y') # 有属性'y'吗?
False
setattr(obj, 'y', 1234) # 设置一个属性'y'
hasattr(obj, 'y') # 有属性'y'吗?
True
getattr(obj, 'y') # 获取属性'y'
1234
obj.y # 获取属性'y'
1234
八.Python|生成器
生成器(generator)是一个特殊的迭代器,它的实现更简单优雅,yield是生成器实现__next__()方法的关键。它作为生成器执行的暂停恢复点,可以对yield表达式进行赋值,也可以将yield表达式的值返回。
也就是说,yield是一个语法糖,内部实现支持了迭代器协议,同时yield内部是一个状态机,维护着挂起和继续的状态。
yield的功能:
1.相当于为函数封装好__iter__和__next__
2.return只能返回一次值,函数就终止了,而yield能返回多次值,每次返回都会将函数暂停,下一次next会从上一次暂停的位置继续执行
def counter(n):
print('start...')
i=0
while i < n:
yield i
i+=1
print('end...')
g=counter(5)
print(g)
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
# print(next(g)) #会报错
start...
0
1
2
3
4
1.列表生成式的缺点
通过列表生成式,我们可以直接创建一个列表。但是,内存数量有限,列表容量肯定不能超过内存大小。再有,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面10%的元素,那后面绝大多数元素占用的空间都白白浪费了。
2.解决办法
如果列表元素中的元素可以按照某种算法推算出来,那是否可以在循环过程中,推算出我们需要的一定数量的元素呢?这样地话,我们就可以灵活地创建需要数量的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。
3.创建generator
下面介绍两种创建generator的方法
第一种方法很简单,只要把一个列表生成式的 [] 改成 (),就创建了一个generator
g = ( x * x for x in range(10) )
g is a generator object
第二种方法是函数中带有yield,那么此函数就不再是函数了,而是一个generator,
def generatorfun():
print('step 1')
yield(10)
print('step 2')
yield 30
4.generator特殊之处
最难理解的就是generator和函数的执行流程不一样。
函数是顺序执行,遇到return语句或者最后一行函数语句就返回。
变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。
通过3节的例子体会这个执行顺序:
gen = generatorfun()
print(next(gen))
print(next(gen))
#以上输出:
step 1
10
step 2
30
#因此,调用第二个next(gen)时,是从第一个yield后一句代码开始执行的。
5.通过捕获去拿返回值
generator对象实际使用时,一般嵌入在for循环中,generator函数的返回值如何拿到呢?必须捕获StopIteration错误,返回值包含在StopIteration的value中。
def generatorfun():
print('step 1')
yield(10)
print('step 2')
yield 30
return "Okay"
gen = generatorfun()
while True:
try:
print(next(gen))
except StopIteration as e:
print("return value: "+ e.value)
break
#输出为:
step 1
10
step 2
30
return value: Okay
九.迭代器
1.迭代概念
上一次输出的结果为下一次输入的初始值,重复的过程称为迭代,每次重复即一次迭代,并且每次迭代的结果是下一次迭代的初始值
注:循环不是迭代
2.可迭代对象:内置__iter__方法的,都是可迭代的对象。
list是可迭代对象,dict是可迭代对象,set也是可迭代对象。
x = [1, 2, 3]
y = iter(x)
z = iter(x)
print(next(y))
print(next(y))
print(next(z))
print(type(x))
print(type(y))
输出
1
2
1
这里x是一个可迭代对象,y和z是两个独立的迭代器,迭代器内部持有一个状态,该状态用于记录当前迭代所在的位置,以方便下次迭代的时候获取正确的元素。迭代器有一种具体的迭代器类型,比如list_iterator,set_iterator。可迭代对象实现了__iter__方法,该方法返回一个迭代器对象。
3.迭代器
(1)为什么要有迭代器?
对于没有索引的数据类型,必须提供一种不依赖索引的迭代方式。
(2)迭代器定义:
迭代器:可迭代对象执行__iter__方法,得到的结果就是迭代器,迭代器对象有__next__方法
它是一个带状态的对象,他能在你调用next()方法的时候返回容器中的下一个值,任何实现了__iter__和__next__()方法的对象都是迭代器,__iter__返回迭代器自身,__next__返回容器中的下一个值,如果容器中没有更多元素了,则抛出StopIteration异常
(3)迭代器的实现
i=[1,2,3].__iter__()
print(i)#迭代器
print(i.__next__())
print(i.__next__())
print(i.__next__())
#print(i.__next__()) #抛出异常:StopIteration
输出
1
2
3
每次调用next()方法的时候做两件事:为下一次调用next()方法修改状态
为当前这次调用生成返回结果
迭代器就像一个懒加载的工厂,等到有人需要的时候才给它生成值返回,没调用的时候就处于休眠状态等待下一次调用。
可迭代对象:只有__iter__方法,执行该方法得到的迭代器对象
迭代器:有__iter__和__next__()方法
注:对于迭代器对象来说,执行__iter__方法,得到的结果仍然是它本身
(5)迭代器的优点和缺点
优点: 1.提供了一种不依赖下标的迭代方式 2.就跌迭代器本身来说,更节省内存
缺点: 1. 无法获取迭代器对象的长度 2. 不如序列类型取值灵活,是一次性的,只能往后取值,不能往前退
十:python中的if_name=='main_'解析
在很多Python代码中,在代码的最下方会看到 if __name__ == '__main__':,这段代码到底有什么用呢?
在理解这个语句的作用前,需要知道的是,一般的Python文件后缀为.py,其可以拿来执行,也可以用来作为模块使用import导入。当Python解析器读取一个源文件时它会执行所有的代码。在执行代码前会定义一些特殊的变量。如果解析器运行的模块(源文件)作为主程序,它将会把__name__变量设置成”__main__”。如果只是引入其他的模块,__name__变量将会设置成模块的名字,模块__name__ 的值通常为模块文件名,不带路径或者文件扩展名。
在代码下方添加 if __name__ == '__main__': 的主要原因是有时你需要你写的模块既可以直接的执行,还可以被当做模块导入到其他模块中去.通过检查是不是主函数,可以让你的代码只在它作为主程序运行时执行,而当其他人调用你的模块中的函数的时候不必执行。
简单来说就是,方便我们代码复用,也可以测试模块。
print(__name__)
输出:
__main__
##修改为:
if __name__ == '__main__':
print('run itself')
else:
print('imported from another module')
输出:
run itself
####注意两个坑
1.先说一下问题。我想根据条件提取部分数据,修改这部分数据某一列的值,原本以为这样做可以修改数据源。结果发现,并没有!
这???修改数据切片,会修改原数据啊! 难道根据掩码提取的数据不是对原数据的引用吗?刚才实验后确认:不一样!
修改数据切片,原数据对应修改,因为切片是对原数据的引用;修改掩码提取的数据,原数据不改变,因为掩码返回的数据指向一块新的内存,不是原来的块引用了!
2.Python写入数据到MySQL
调用pymysql包,写入数据到表,遇到一个问题。问题描述。一张 mysql 表 t,数据类型有字符型字段 field_s,数值型 field_n。 python提供数据源,调用pymysql 包接口写入数据到 t.
一般都会这么做: 插入脚本为insert into t (field_s, field_n)values (%s, %f), (‘s_val’, float(n_val) ) 调用 execute 接口,commit 后提交。调试程序,发现报错:a number is required, not str. 实际项目中由于插入的字段比较多,本以为有些字段类型未对应好,仔细检查后,确认所有字段类型都对应一致。那是什么问题呢?
经过查询发现,插入的所有字段,格式要求一律为 %s, 因此将上面脚本修改为:insert into t (field_s, field_n) values (%s, %s), (‘s_val’, float(n_val) ) 后,问题得到解决。
python怎么定义a_python一些基础知识2相关推荐
- Python学习--最完整的基础知识大全
##Python学习–最完整的基础知识大全 关于python的基础知识学习,网上有很多资料,今天我就把我收藏的整理一下分享给大家! #####菜鸟教程python2 #####菜鸟教程python3 ...
- 小猪的Python学习之旅 —— 1.基础知识储备
小猪的Python学习之旅 -- 1.基础知识储备 引言: (文章比较长,建议看目录按需学习-) 以前刚学编程的时候就对Python略有耳闻,不过学校只有C,C++,Java,C#. 和PHP有句&q ...
- Python系列 之 matplotlib库 基础知识
Python系列 之 matplotlib库 基础知识学习 Pyplot 简单示例 中文显示问题 注册全局字体 font_manager.FontProperties注册字体 Figure Figur ...
- 下列哪个不是python元组的定义方式_Python基础知识笔试
Python基础知识笔试 单选题(2.5分*20题) 1. 下列哪个表达式在Python中是非法的? B A. x = y = z = 1 B. x = (y = z + 1) C. x, y = y ...
- python常用变量名_python基础知识整理
Python Python开发 Python语言 python基础知识整理 序言:本文简单介绍python基础知识的一些重要知识点,用于总结复习,每个知识点的具体用法会在后面的博客中一一补充程序: 一 ...
- python中用str乘方_Python基础知识
Python2与Python3的区别: (这里只列举自己总结的几点) Python2: 源码不标准 混乱 重复代码过多 默认使用的编码方式是ASCII码 # 解决对应编码问题 在首行增加 #-*-e ...
- [Python学习] 专题五.列表基础知识 二维list排序、获取下标和处理txt文本实例
通常测试人员或公司实习人员需要处理一些txt文本内容,而此时使用Python是比较方便的语言.它不光在爬取网上资料上方便,还在NLP自然语言处理方面拥有独到的优势.这篇文章主要简单的介绍使用Pytho ...
- python二级考试选择题公共基础知识_计算机二级Python易忘考点整理
事先声明,这里记录的是我刷二级题时遇到的不熟悉的问题时记录下来的笔记.可能并不适合所有人,仅供参考. 任何问题请联系邮箱:admin@likehide.com (因为不常上网站,所以留言和私信可能无法 ...
- python bif_小猪的Python学习之旅 —— 1.基础知识储备
引言:(文章比较长,建议看目录按需学习-) 以前刚学编程的时候就对Python略有耳闻,不过学校只有C,C++,Java,C#. 和PHP有句"PHP是最好的语言" 这种家喻户晓的 ...
最新文章
- CTEX - 在线文档 - TeX/LaTeX 常用宏包
- 11.2.4 jQuery动画
- 影响用户体验的4个因素
- 互联网高并发之Hystrix实现服务隔离和降级
- echarts柱状图的数据差距过大影响美观
- 关于计算机信息技术论文,信息技术论文
- 点到线的距离计算公式
- 机器学习进阶 第一节 第一课
- 9个offer,12家公司,35场面试,从微软到谷歌,我的求职之路!
- pythonpil安装教程_成功安装PIL步骤
- ftp服务器有哪些作用,FTP是什么意思 FTP服务器有什么作用及功能
- HTML5期末大作业:旅游网页设计与实现——四川成都-(9页 带购物车)
- python利用scipy.integrate中的odeint方法解微分方程
- 解决 Minecraft 官方启动器 报错找不到 launcher.dll / LoadErrorNotPresent 的解决方法
- 2021全国人工智能师资培训入高校,百度携手哈工大探索AI师资更多可能
- python web前端 java ui学哪个好_学IT选Java还是Python?就业发展有何区别?
- Vue中监测数据变化
- CocosCreator 计时器
- C语言大小端数据转换总结
- 蚂蚁 Service Mesh 大规模落地实践与展望