全局变量补充

python自己添加了些全局变量

print(vars())
"""
结果:
{'__name__': '__main__',
'__doc__': None,
'__package__': None,
'__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00795650>,
'__spec__': None,
'__annotations__': {},
'__builtins__': <module 'builtins' (built-in)>,
'__file__': 'C:/Users/Sullivan/PycharmProjects/q1/day12/global.py',
'__cached__': None}
"""

这些全局变量的作用

#__doc__ 包含py文件的注释,文件的注释在——文件内容的最上面用三引号引起来
print(__doc__) #__file__ 包含当前文件的路径
print(__file__) #__package__ 对于单读文件的package是没有意义的,代表当前的py文件在哪几个文件夹下
print(__package__)#当前文件没有,会返回None
from day2 import homework
print(homework.__package__) #文件夹套文件夹时用点"."区分
#结果:day2 #__cached__ 缓存,对于py文件是可以设置一个缓存的,python2里没有,了解即可
print(__cached__)#当前文件也有,会返回None
from day2 import homework
print(homework.__cached__)
#结果:C:\Users\Sullivan\PycharmProjects\q1\day2\__pycache__\homework.cpython-36.pyc #__name__ 如果当前执行的是当前文件,它的__name__就是__main__,其它的不管是导入还是其它的操作__name__就是文件名
print(__name__)
#结果__main__
from day2 import homework
print(homework.__name__)
#结果:day2.homework #__builtins__ 里边放的就是内置函数 #__loader__和__spec__ 都是p3中新加的
# 因为程序的入口文件就是用户当前执行的文件,所以以后写主程序文件的时候
if __name__ == "__main__":
execute()
#防止其他文件导入该文件时,执行主函数

name的实际应用

#利用sys,os模块和__file__变量,把路径添加到system path中

import os,sys
p1 = os.path.dirname(__file__) #获取当前路径
p2 = "bin"
my_dir = os.path.join(p1,p2) #字符串拼接,拼接出新路径 sys.path.append(my_dir) #添加到system path里面

file的实际应用

Python参数传递

Python参数传递 有引用传递&值传递两种

值传递:方法调用时,实际参数把它的值传递给对应的形式参数,方法执行中形式参数值的改变不影响实际参数的值。

a1 = 520
a2 = a1
print(a1,a2)
结果:520 520
a2 = a1 + 1
print(a1,a2)
结果:520 521

引用传递:也称地址传递,在方法调用时,实际上是把参数的引用(传的是地址,而不是参数的值)传递给方法中对应的形式参数,在方法执行中,对形式参数的操作实际上就是对实际参数的操作,方法执行中形式参数值的改变将会影响实际参数的值。

a1 = [1,2]
a2 = a1
a2.append(3)
print(a1)
结果:[1, 2, 3]
print(a2)
结果:[1, 2, 3]  

Python中,数字、字符或者元组等不可变对象类型都属于值传递,而字典dict或者列表list等可变对象类型属于引用传递

如果要想修改新赋值后原对象不变,则需要用到python的copy模块,即对象拷贝。对象拷贝又包含浅拷贝和深拷贝。下面用例子来说明

例一

import copy
l1 = [[1, 2], 3] l2 = copy.copy(l1)
l2.append(4)   #因为浅拷贝之拷贝第一层,所以对第一层操作不会影响l1
l2[0].append(5)   #因为浅拷贝只拷贝的第一层,所以对第二层的操作还是值传递,所以l1和l2中都有列表的第一个元素都会添加一个5
print(l1)
print(l2)
结果:
[[1, 2, 5], 3]
[[1, 2, 5], 3, 4]

例二

l1 = [[1, 2], 3]
l3 = copy.deepcopy(l1) l3[0].append(6)
print(l1)
print(l3) #深拷贝全部拷贝,所以只是l3的值变了,l1并没有改变
# 结果:
[[1, 2], 3]
[[1, 2, 6], 3]  

从上例可以看出,copy.copy属于浅拷贝,拷贝的是第一层list,而copy.deepcopy属于深拷贝,对list所有子元素都进行深拷贝。  

字符串格式化

Python的字符串格式化有两种方式: 百分号方式、format方式

百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存。

1、百分号方式

%[(name)][flags][width].[precision]typecode
  • (name)      可选,用于选择指定的key
  • flags          可选,可供选择的值有:
    • +       右对齐;正数前加正好,负数前加负号;只有这个会在输出后给整数加上正号(+)
    • -        左对齐;正数前无符号,负数前加负号;
    • 空格    右对齐;正数前加空格,负数前加负号;
    • 0        右对齐;正数前无符号,负数前加负号;用0填充空白处
  • width         可选,占有宽度
  • .precision   可选,小数点后保留的位数
  • typecode    必选
    • s,获取传入对象的__str__方法的返回值,并将其格式化到指定位置
    • r,获取传入对象的__repr__方法的返回值,并将其格式化到指定位置
    • c,整数:将数字转换成其unicode对应的值,10进制范围为 0 <= i <= 1114111(py27则只支持0-255);字符:将字符添加到指定位置
    • o,将整数转换成 八  进制表示,并将其格式化到指定位置
    • x,将整数转换成十六进制表示,并将其格式化到指定位置
    • d,将整数、浮点数转换成 十 进制表示,并将其格式化到指定位置
    • e,将整数、浮点数转换成科学计数法,并将其格式化到指定位置(小写e)
    • E,将整数、浮点数转换成科学计数法,并将其格式化到指定位置(大写E)
    • f, 将整数、浮点数转换成浮点数表示,并将其格式化到指定位置(默认保留小数点后6位)
    • F,同上
    • g,自动调整将整数、浮点数转换成 浮点型或科学计数法表示(超过6位数用科学计数法),并将其格式化到指定位置(如果是科学计数则是e;)
    • G,自动调整将整数、浮点数转换成 浮点型或科学计数法表示(超过6位数用科学计数法),并将其格式化到指定位置(如果是科学计数则是E;)
    • %,当字符串中存在格式化标志时,需要用 %%表示一个百分号

注:Python中百分号格式化是不存在自动将整数转换成二进制表示的方式

功能示例:

# %[(name)][flags][width].[precision]typecode

s = ["i am %s,age %d" % ('ciri',18)]
# (name)
s = "i am %(n1)s,age %(n2)d" % {"n1":"ciri","n2":16}
s = "i am %(n1)s,age %(n1)s" % {"n1":"ciri"} #也可以两个共用一个值 #flags和width一般放到一起用,一般用不到
#字符
s = "i am %(n1)+10s ellie" % {"n1":"ciri"}
s = "i am %(n1)-10s ellie" % {"n1":"ciri"}
s = "i am %(n1) 10s ellie" % {"n1":"ciri"}
s = "i am %(n1)010s ellie" % {"n1":"ciri"}
#数字
s = "age %(n2)+10d ellie" % {"n2":16}
s = "age %(n2)+10d ellie" % {"n2":-16} s = "age %(n2)-10d ellie" % {"n2":16}
s = "age %(n2)-10d ellie" % {"n2":-16} s = "age %(n2) 10d ellie" % {"n2":16}
s = "age %(n2) 10d ellie" % {"n2":-16} s = "age %(n2)010d ellie" % {"n2":16}
s = "age %(n2)010d ellie" % {"n2":-16} #precision——默认输出6位小数
s = "age %f ellie" % 1.2
s = "age %.2f ellie" % 1.2 #指定小数保留几位

常用格式化:

tpl = "i am %s" % "alex"

tpl = "i am %s age %d" % ("alex", 18)

tpl = "i am %(name)s age %(age)d" % {"name": "alex", "age": 18}

tpl = "percent %.2f" % 99.97623

tpl = "i am %(pp).2f" % {"pp": 123.425556, }

tpl = "i am %.2f %%" % {"pp": 123.425556, }

2、Format方式

[[fill]align][sign][#][0][width][,][.precision][type]
都是中括号[],所以参数都可以省略
  • fill           【可选】空白处填充的字符
  • align        【可选】对齐方式(需配合width使用)
    • <,内容左对齐
    • >,内容右对齐(默认)
    • =,内容右对齐,将符号放置在填充字符的左侧,且只对数字类型有效。 即使:符号+填充物+数字
    • ^,内容居中
  • sign         【可选】有无符号数字
    • +,正号加正,负号加负;
    •  -,正号不变,负号加负;
    • 空格 ,正号空格,负号加负;
  • #            【可选】对于二进制、八进制、十六进制,如果加上#,会显示 0b/0o/0x,否则不显示
  • ,            【可选】为数字添加分隔符,如:1,000,000
  • width       【可选】格式化位所占宽度
  • .precision 【可选】小数位保留精度
  • type         【可选】格式化类型
    • 传入” 字符串类型 “的参数

      • s,格式化字符串类型数据
      • 空白,未指定类型,则默认是None,同s
    • 传入“ 整数类型 ”的参数
      • b,将10进制整数自动转换成2进制表示然后格式化
      • c,将10进制整数自动转换为其对应的unicode字符
      • d,十进制整数
      • o,将10进制整数自动转换成8进制表示然后格式化;
      • x,将10进制整数自动转换成16进制表示然后格式化(小写x)
      • X,将10进制整数自动转换成16进制表示然后格式化(大写X)
    • 传入“ 浮点型或小数类型 ”的参数
      • e, 转换为科学计数法(小写e)表示,然后格式化;
      • E, 转换为科学计数法(大写E)表示,然后格式化;
      • f , 转换为浮点型(默认小数点后保留6位)表示,然后格式化;
      • F, 转换为浮点型(默认小数点后保留6位)表示,然后格式化;
      • g, 自动在e和f中切换
      • G, 自动在E和F中切换
      • %,显示百分比(默认显示小数点后6位)

常用格式化:

# [[fill]align][sign][#][0][width][,][.precision][type]

tpl = "i am {}, age {}".format("seven", 18)
tpl = "i am {}, age {}".format(*["seven", 18,'ciri']) #传入列表,列表的元素可以比前面的内容所
#可以传索引
tpl = "i am {0}, age {1}".format("seven", 18)
tpl = "i am {0}, age {1}".format(*["seven", 18])
#通过name获取
tpl = "i am {name}, age {age}".format(name="seven", age=18)
tpl = "i am {name}, age {age}".format(**{"name": "seven", "age": 18})#传字典要穿加上**
#第一个0表示拿第几个元素
tpl = "i am {0[0]}, age {0[1]}".format([1, 2, 3], [11, 22, 33])
#分别接收字符串、数字和浮点数
tpl = "i am {:s}, age {:d}, money {:f}".format("seven", 18, 88888.1)
tpl = "i am {:s}, age {:d}".format(*["seven", 18]) tpl = "i am {name:s}, age {age:d}".format(name="seven", age=18)
tpl = "i am {name:s}, age {age:d}".format(**{"name": "seven", "age": 18}) tpl = "numbers: {:b},{:o},{:d},{:x},{:X}, {:%}".format(15, 15, 15, 15, 15, 15.87623, 2)
tpl = "numbers: {0:b},{0:o},{0:d},{0:x},{0:X}, {0:%}".format(15)
tpl = "numbers: {num:b},{num:o},{num:d},{num:x},{num:X}, {num:%}".format(num=15)

生成器——generator

列表生成器

# 先到 for x in range(10) 取元素,再把取出来的元素按照 前面的内容(x,x+1,x*2) 进行操作,然后把结果依次放到列表中

a = [x for x in range(10)]
print(a)
a = [x+1 for x in range(10)]
print(a)
a = [x*2 for x in range(10)]
print(a)
结果:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10

赋值一种方法 

t = ('ciri',8)
a,b = t #值和变量的个数要相同,否则会报错 print(a)
print(b)
结果:
ciri
8

如何创建生成器?

方法一:小括号的方式

#把列表生成式的中括号,改成小括号,就变成了一个生成器
s = (x for x in range(10))
print(s) # <generator object <genexpr> at 0x03726360>
#输出的是一个生成器对象,所有的值压根就没有被创建出来(重点)
之前的列表生成式生成了10个值,就相当于10盘菜,已经做出来了,想什么时候成就什么时候吃,想什么时候调动就什么时候调用,想吃第几道就吃第几道。
生成器就相当于,厨师脑子里的10道菜,想吃的时候才做出来,你不吃就不会做出来,只能按顺序吃(0,1...8,9),不能隔着吃,也不能倒着吃

方法二:yield方式

def func():
print('ok')
yield 1
print('ok2')
yield 2 print(func) # <function func at 0x03163540> 可以看出func还是一个函数 func() #不会执行函数,此时func()是一个生成器对象 print(func())
# <generator object func at 0x034764B0> 可以看出 func加上括号() 是一个生成器对象

yield的执行过程

def func():
print('ok')
yield 1
print('ok2')
yield 2 next(func())
next(func())
结果:
ok
ok2 for i in func():
print(i)
结果:
ok
1
ok2
2

如何使用生成器中的对象?

s = (x for x in range(10))
print(s) # 方法一:
print(s.__next__())#内部特殊的方法,不建议用 # 方法二:
#python3中新加的方法
print(next(s)) #以后就用这种方法 # 方法三:
#python2中可以直接调用next方法
print(s.next) # 方法四:
for i in s:
print(i) #for就是内部调用next方法

斐波那契数列

def fib(max):
n,b,a = 0,0,1
while n<max:
print(b) #最开始的值
yield b
b, a = a, b + a #会先把b+a计算出来
n = n + 1 g = fib(8)
next(g)
next(g)
next(g)
next(g)
b, a = a, b + a为什么这个可以,把a的值赋值给b,b+a的值赋值给a

b = a
a = b + a 这个不行 #因为b, a = a, b + a会先计算出来b+a的值

补充:b, a = a, b + a为什么这个可以

send方法

send和next的区别就是,send可以给yield前面的变量传值

def bar():
print('ok')
count = yield 1
print(count) #第二次进来,就会直接把send的值,直接传给yield前的参数count
yield 2 b = bar() #b.send('ciri') 会报错,因为第一次进来,执行到到yield就冻结了,出去了,所以第一次不知道给谁赋值,所以就不能用send传参数 ret1 = b.send(None) #用send第一次进入时,只能这么写,等价于next(b)
print(ret1) #结果 1 ret2 = b.send('ciri')
print(ret2) #结果:2

实例:用yield实现伪并发

#做和吃是同时发生的
import time def consumer(name):
print("%s 准备吃包子啦!" % name)
while True:
baozi = yield print("包子[%s]来了,被[%s]吃了!" %(baozi,name)) def producer(name):
c = consumer('A')
c2 = consumer('B')
next(c)
next(c2)
print("老子开始准备做包子了")
for i in range(10):
time.sleep(1)
print("做了2个包子")
c.send(i)
c2.send(i)
producer("ciri")

迭代器——iterator  

生成器都是迭代器,迭代器不一定是生成器 

如何创建一个迭代器?

#iter方法就做一件事情,返回了一个迭代器对象

li = [1,2,3,4]
d = iter(li)
print(d)
# <list_iterator object at 0x034A4770> iterator迭代器,iterable可迭代对象

什么是迭代器?
  满足两个条件:1.有iter方法  2.有next方法

for循环后面加的是什么?
  可迭代对象

什么是可迭代对象?
  现象上——能进行 for循环的,都是可迭代对象
  本质上——内部有iter方法的,就是可迭代对象

执行迭代器

li = [1,2,3,4]

d = iter(li)    #iter方法就做了一件事情,返回了一个迭代器对象

print(next(d))
print(next(d))

补充:for循环 执行时的内部操作三件事

  1. 调用可迭代对象的iter方法,返回一个迭代器对象
  2. 调用迭代器的next方法
  3. 处理stopiteration异常

实例:操作文件

f = open('abc.txt','r')
for i in f.readlines(): #假如文件很大的话,会全部都放到内存中去
pass
for i in f(): #这里的f就是一个可迭代对象,节省内存空间
pass

练习:使用文件读取,找出文件中最长的行

max(len(x.strip()) for x in open('/hello/abc','r'))

   

Python的字符串格式化有两种方式: 百分号方式、format方式

百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存。

Python学习日记(十)—— 杂货铺(全局变量补充、Python参数传递、字符串格式化、迭代器、生成器)的更多相关文章

  1. Python学习日记(一)——初识Python

    Python的优势 互联网公司广泛使用python来做的事一般有:自动化运维.自动化测试.大数据分析.爬虫.Web等. Python与其他语言 C和Python.Java.C#: C  语言:代码编译 ...

  2. Python学习日记(十八) 序列化模块

    什么是序列? 就是每一个元素被有序的排成一列 什么是序列化? 就是将原本的列表.字典等内容转化成字符串的过程 什么时候会用到序列化? 数据存储(把数据放在文件.数据库),网络传输等 序列化的目的 1. ...

  3. Python学习日记(十六) time模块和random模块

    time模块 python表示时间的三种方式:时间戳.元祖(struct_time).格式化时间字符串 三种格式之间的转换: 1.时间戳 就是从1970年1月1日0点0分0秒开始按秒计算的偏移量,时间 ...

  4. Python学习日记(十二) 匿名函数

    匿名函数: 未解决一些简单的需求而设计的函数 语法: func = lambda x : x**2 func:函数名 lambda:类似def的关键字 x:参数 x**2:返回值表达式 适用内置函数: ...

  5. Python学习日记(十) 生成器和迭代器

    使用dir()我们可以知道这个数据类型的内置函数有什么方法: print(dir(int)) print(dir(bool)) print(dir([])) print(dir({})) print( ...

  6. Python学习日记(十九) 模块导入

    模块导入 当文件夹中有这样一个自定义的command模块 在它的内部写下下列代码: print('这个py文件被调用!') def fuc(): print('这个函数被调用!') 然后我们在comm ...

  7. Python学习日记(十五) collections模块

    在内置函数(dict.list.set.tuple)的基础上,collections模块还提供了几个其他的数据类型:Counter.deque.defaultdict.namedtuple和Order ...

  8. Python学习日记(十四) 正则表达式和re模块

    正则表达式: 它是字符串的一种匹配模式,用来处理字符串,可以极大地减轻处理一些复杂字符串的代码量 字符组:它是在同一位置可能出现的各种字符组成了一个字符组,用[]表示,但是它的结果只能是一个数字或者一 ...

  9. Python 学习 第十篇 CMDB用户权限管理

    Python 学习 第十篇 CMDB用户权限管理 2016-10-10 16:29:17 标签: python 版权声明:原创作品,谢绝转载!否则将追究法律责任. 不管是什么系统,用户权限都是至关重要 ...

随机推荐

  1. php 环境搭建问题

    项目过程中需要用到 PHP环境 https://www.cnblogs.com/cyrfr/p/6483529.html APACHE无法启动:THE REQUEST OPERATION HAS FA ...

  2. Ajax中解析Json的两种方法

    eval(); //此方法不推荐 JSON.parse(); //推荐方法 一.两种方法的区别 我们先初始化一个json格式的对象: var jsonDate = '{ "name" ...

  3. Django 之一些request封装的常用功能

    一些常用的request对象属性 介绍 HTTP 应用的信息是通过 请求报文 和 响应报文 传递的,关于更多的相关知识,可以阅读<HTTP权威指南>获得. 其中 请求报文 由客户端发送,其 ...

  4. 客户端相关知识学习(十二)之iOS H5交互Webview实现localStorage数据存储

    前言 最近有一个需求是和在app中前端本地存储相关的,所以恶补了一下相关知识 webView开启支持H5 LocalStorage存储 有些时候我们发现写的本地存储没有起作用,那是因为默认WebVie ...

  5. 【转载】salesforce 零基础开发入门学习(二)变量基础知识,集合,表达式,流程控制语句

    salesforce 零基础开发入门学习(二)变量基础知识,集合,表达式,流程控制语句 salesforce如果简单的说可以大概分成两个部分:Apex,VisualForce Page. 其中Apex ...

  6. 如何搭建一个基于nuxt.js的项目

    介绍 nuxt.js(中文官方文档)是vue.js的一个通用型应用框架,有了之前搭建vue项目的过程之后,搭建一个nuxt项目就会十分简单. 搭建步骤 1.打开命令提示符,进入到相关文件夹下: 2.使 ...

  7. 6.Java集合-LinkedList实现原理及源码分析

    Java中LinkedList的部分源码(本文针对1.7的源码) LinkedList的基本结构 jdk1.7之后,node节点取代了 entry ,带来的变化是,将1.6中的环形结构优化为了直线型链 ...

  8. ASE19 团队项目 alpha 阶段 Frontend 组 scrum9 记录

    本次会议于11月14日,11:30 在微软北京西二号楼13158,持续15分钟. 与会人员:Jingyi Xie, Jiaqi Xu, Jingwei Yi, Hanyue Tu 请假: Ziwei ...

  9. 用js刷剑指offer(反转链表)

    题目描述 输入一个链表,反转链表后,输出新链表的表头. 牛客网链接 js代码 /*function ListNode(x){ this.val = x; this.next = null; }*/ f ...

  10. 火狐新版移除developer Toolbar和无法关闭自动更新的解决

    随着火狐的不断更新已经更新到66版本了,近期注意到有个问题是火狐经常提示更新,更新了没多久,又时不时跳出更新的提示,不胜其烦. 在火狐的前期的版本中(大概4年之前吧)在Options菜单里是可以设置从 ...