Python迭代器生成器,私有变量及列表字典集合推导式(二)
1 python自省机制
这个是python一大特性,自省就是面向对象的语言所写的程序在运行时,能知道对象的类型,换句话说就是在运行时能获取对象的类型,比如通过 type(),dir(),getattr(),hasattr(),isinstance().
a = [1,2,3] b = {'a':1,'b':2,'c':3} c = True print(type(a),type(b),type(c)) # <type 'list'> <type 'dict'> <type 'bool'> print(isinstance(a,list)) # True
2 python中列表推导式,字典推导式,集合推导式
列表生成式 : 中括号括起来表示列表
(1)[exp for iter_var in iterable if_exp] #工作过程: 1 迭代iterable中的每个元素,每次迭代都先判断if_exp表达式结果为真,如果为真则进行下一步,如果为假则进行下一次迭代; 2 把迭代结果赋值给iter_var,然后通过exp得到一个新的计算值; 3 最后把所有通过exp得到的计算值以一个新列表的形式返回。 #相当于这样的过程: L = [] for iter_var in iterable: if_exp: L.append(exp) #也可以循环嵌套 (2)[exp for iter_var_A in iterable_A for iter_var_B in iterable_B] 工作过程: 每迭代iterable_A中的一个元素,就把ierable_B中的所有元素都迭代一遍。 #相当于这样的过程: L = [] for iter_var_A in iterable_A: for iter_var_B in iterable_B: L.append(exp)
字典推导式:大括号括起来,表示为字典
d = {key: value for (key, value) in iterable} #快速更改字典key,value mcase = {'a': 10, 'b': 34} mcase_frequency = {v: k for k, v in mcase.items()} print(mcase_frequency) # Output: {10: 'a', 34: 'b'}
集合推导式: 跟列表推导式也是类似的 唯一的区别在于它使用大括号{},表示结果为集合
squared = {x**2 for x in [1, 1, 2]} print(squared) # Output: set([1, 4])
3 Python中单下划线和双下划线
>>> class MyClass(): ... def __init__(self): ... self.__superprivate = "Hello" ... self._semiprivate = ", world!" ... >>> mc = MyClass() >>> print(mc.__superprivate) #私有变量不能直接访问 #print(mc._Myclass__superprivate) 也可以访问,但是不建议这样访问 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: myClass instance has no attribute '__superprivate' >>> print(mc._semiprivate) , world! >>> print(mc.__dict__) {'_MyClass__superprivate': 'Hello', '_semiprivate': ', world!'}
-
__foo__
: 一种约定,Python内部的名字,用来区别其他用户自定义的命名,以防冲突,就是例如__init__()
,__del__()
,__call__()
这些特殊方法 -
_foo
: 一种约定,用来指定变量私有.程序员用来指定私有变量的一种方式.不能用from module import * 导入,其他方面和公有一样访问; -
__foo
: 意义: 私有变量不能直接访问, 因为解析器用_classname__foo
来代替这个名字,以区别和其他类相同的命名,它无法直接像公有成员一样随便访问,但是可以通过对象名._类名__xxx这样的方式可以访问,但是不建议这样来访问.
4 字符串格式化:%和.format
.format在许多方面看起来更便利.对于%
最烦人的是它无法同时传递一个变量和元组.你可能会想下面的代码不会有什么问题:
"hi there %s" % name
但是,如果name恰好是(1,2,3),它将会抛出一个TypeError异常.为了保证它总是正确的,你必须这样做:
"hi there %s" % (name,) # 提供一个单元素的数组而不是一个参数
但是有点丑 .format就没有这些问题.而且format可以实现模运算符(%)不能做的事
tu = (12,45,22222,103,6) print('{0} {2} {1} {2} {3} {2} {4} {2}'.format(*tu)) #结果 12 22222 45 22222 103 22222 6 22222
另一点format()
作为一个函数,可以用作其他函数的参数:
li = [12,45,78,784,2,69,1254,4785,984] print(map('the number is {}'.format,li)) from datetime import datetime,timedelta once_upon_a_time = datetime(2010, 7, 1, 12, 0, 0) delta = timedelta(days=13, hours=8, minutes=20) gen =(once_upon_a_time + x*delta for x in xrange(20)) print '\n'.join(map('{:%Y-%m-%d %H:%M:%S}'.format, gen)) 2010-07-01 12:00:00 2010-07-14 20:20:00 2010-07-28 04:40:00 2010-08-10 13:00:00 2010-08-23 21:20:00 2010-09-06 05:40:00 2010-09-19 14:00:00 2010-10-02 22:20:00 2010-10-16 06:40:00 2010-10-29 15:00:00 2010-11-11 23:20:00 2010-11-25 07:40:00 2010-12-08 16:00:00 2010-12-22 00:20:00 2011-01-04 08:40:00 2011-01-17 17:00:00 2011-01-31 01:20:00 2011-02-13 09:40:00 2011-02-26 18:00:00 2011-03-12 02:20:00
5 迭代器和生成器
将列表生成式中[]改成() 之后数据结构发生改变 ,从列表变为生成器. 在for...in...
语句中的都是可迭代的:比如lists,strings,files…因为这些可迭代的对象你可以随意的读取,所以非常方便易用,但是你必须把它们的值放到内存里,当它们有很多值时就会消耗太多的内存.
>>> L = [x*x for x in range(10)] #迭代器 >>> L [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]#列表 >>> g = (x*x for x in range(10)) #生成器 >>> g <generator object <genexpr> at 0x0000028F8B774200>#生成器对象
通过列表生成式,可以直接创建一个列表。但是受到内存限制,列表容量肯定是有限的。而且,创建一个包含百万元素的列表,不仅是占用很大的内存空间,如:我们只需要访问前面的几个元素,后面大部分元素所占的空间都是浪费的。因此,没有必要创建完整的列表(节省大量内存空间)。在Python中,我们可以采用生成器:边循环,边计算的机制—>generator
生成器的关键字yield: 理解Yield
你必须先理解当你调用函数的时候,函数里的代码并没有运行.函数仅仅返回生成器对象
>>> def createGenerator(): ... mylist = range(3) ... for i in mylist: ... yield i*i ... >>> mygenerator = createGenerator() # 创建生成器 >>> print(mygenerator) # mygenerator is an object! <generator object createGenerator at 0xb7555c34> >>> for i in mygenerator: ... print(i) 0 1 4
当你的函数要返回一个非常大的集合并且你希望只读一次的话,那么它就非常的方便了.
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
java之观察者模式
一、Observer模式定义对象间的一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。JDK里提供的observer设计模式的实现由java.util.Observable类和 java.util.Observer接口组成。从名字上可以清楚的看出两者在Observer 设计模式中分别扮演的角色:Observer是观察者角色,Observable是被观察目标(subject)角色。 二、观察者模式的优点: 1、 Subject和Observer之间是松耦合的,分别可以各自独立改变。 2、 Subject在发送广播通知的时候,无须指定具体的Observer,Observer可以自己决定是否要订阅Subject的通知。 3、 遵守大部分GRASP原则和常用设计原则,高内聚、低耦合。 三、观察者模式的缺陷: 1、 松耦合导致代码关系不明显,有时可能难以理解。(废话) 2、 如果一个Subject被大量Observer订阅的话,在广播通知的时候可能会有效率问题。(毕竟只是简单的遍历) 四、结构图 1)注册时: 2)Subject触发时: 五、这里写了一...
- 下一篇
(6)Python集合
知识在于点滴积累
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- SpringBoot2整合Redis,开启缓存,提高访问速度
- MySQL8.0.19开启GTID主从同步CentOS8
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- CentOS8编译安装MySQL8.0.19
- CentOS8安装Docker,最新的服务器搭配容器使用