浅拷贝:html
a = [1,2,3,4] b = a print(id(a)) #2540558597256 print(id(b)) #2540558597256 a.append(5) print(a) #[1, 2, 3, 4, 5] print(b) #[1, 2, 3, 4, 5]
深拷贝:python
b = copy.deepcopy(a)算法
b获得的内容与a的内容彻底同样,地址不同。编程
就算a中有对象引用,b中对应的引用的对象依然是内容同样,地址不同。json
递归拷贝缓存
注意:
若是是一个不可变对象(内部存储仍是不可变对象),深拷贝的结果 = 浅拷贝,地址同样多线程
copy.copy闭包
import copy a = [1,2,3,4] #至关于深拷贝 b = copy.copy(a) print(id(a)) print(id(b)) a.append(5) print(a) print(b) print('*'*50) a = (1,2,3,4) #至关于浅拷贝 b = copy.copy(a) print(id(a)) print(id(b)) ---------------------------- a = [11,22,33] b = [44,55,66] c = [a,b] d = copy.copy(c) print(id(c)) print(id(d)) print(c) print(d) print('*'*50) a.append(120) #c[0].append(120) print(c) print(d) print('*'*50) a = [11,22,33] b = [44,55,66] c = (a,b) d = copy.copy(c) print(id(c)) print(id(d)) print(c) print(d) print('*'*50) a.append(120) #c[0].append(120) print(c) print(d)
私有的内容,对外不能直接访问。 若是想对外访问,须要提供能够访问的方法,好比这里的getMoney,setMoney 调用的时候比较麻烦。 能不能像操做属性同样呢? 属性名 = property(get,set)
class Money(object): def __init__(self): self.__money = 0 def getMoney(self): return self.__money def setMoney(self, value): if isinstance(value, int): self.__money = value else: print("error:不是整型数字") m = Money() print(m.getMoney()) m.setMoney(10) print(m.getMoney())
class Money(object): def __init__(self): self.__money = 0 def getMoney(self): return self.__money def setMoney(self, value): if isinstance(value, int): self.__money = value else: print("error:不是整型数字") money = property(getMoney,setMoney) m.money = 120 #至关于上面的m.setMoney(120) print(m.money) #至关于上面的m.getMoney #或者是 print(Money.money)
class Money(object): def __init__(self): self.__money = 0 @property def money(self): return self.__money @money.setter def money(self, value): if isinstance(value, int): self.__money = value else: print("error:不是整型数字") m = Money() print(m.money) m.money = 120 print(m.money)
若是列表元素能够按照某种算法推算出来,那咱们是否能够在循环的过程当中不断推算出后续的元素呢?这样就没必要建立完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。app
要建立一个生成器,有不少种方法。第一种方法很简单,只要把一个列表生成式的 [ ] 改为 ( )dom
#列表生成式 ls = [x for x in range(100)] print(ls)
#生成器 ge = (x**2 for x in range(1000)) print(ge) print(type(ge)) i = 0 while i<19: next(ge) i+=1 print(next(ge))
总结
生成器保存的是算法,每次调用 next(G) ,就计算出 G 的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出 StopIteration 的异常。固然,这种不断调用 next() 实在是太变态了,正确的方法是使用 for 循环,由于生成器也是可迭代对象。因此,咱们建立了一个生成器后,基本上永远不会调用 next() ,而是经过 for 循环来迭代它,而且不须要关心 StopIteration 异常。
yield 值
def fib(times): print('0....') n = 0 a,b = 0,1 while n<times: print('1....') yield b print('2....') a,b = b,a+b n+=1 print('3....') ge = fib(5) print(ge) print('*'*50) m = 0 while m<5: print(next(ge)) m+=1
第一种和第二种,一旦生成器肯定,算法不能改变。
这里的例子,定义了变量(temp),可使用send发送参数,发给这里变量。
根据这个变量的值的不一样,能够改变算法的逻辑。
因此,这种写法的做用:在运行过程当中,能够改变算法
def gen(): i = 0 while i<1000: temp = yield i if temp==True: #逻辑代码 print('执行A计划') i+1 else: #逻辑代码 print('执行B计划') i+=2 myGenerator = gen() ret = next(myGenerator) print(ret) #一、为当前中止的代码的左侧变量赋值 #二、生成器往下走一个行,返回yield值 ret = myGenerator.send(True) print(ret) ret = myGenerator.send(False) print(ret)
import time def test1(): while True: print("--王者荣耀--") #time.sleep(2) yield None def test2(): while True: print("--music--") yield None def main(): t1 = test1() t2 = test2() while True: t1.__next__() t2.__next__() main()
总结
生成器的特色:
迭代是访问集合元素的一种方式。迭代器是一个能够记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到全部的元素被访问完结束。迭代器只能往前不会后退。
以直接做用于 for 循环的数据类型有如下几种:
这些能够直接做用于 for 循环的对象统称为可迭代对象: Iterable 。
isinstance(对象,Iterable)
若是结果为True
只是表示,这些对象以使用for循环迭代遍历,可使用next
import collections ge = (x for x in range(10)) print(isinstance(ge,collections.Iterable)) #True print(isinstance(ge,collections.Iterator)) #True print(next(ge)) #0 print('************************华丽的分割线************************') ls = [x for x in range(10)] print(isinstance(ls,collections.Iterable)) #True print(isinstance(ls,collections.Iterator)) #False for i in ls: print(i) #0-9的数
ls = [33,4,5,6,7,8] it=iter(ls) for i in range(len(ls)): print(next(it)) #33-8的数
总结
def test1(): print("--- in test1 func----") #调用函数 test1() #此是ret引用函数 ret = test1 print(id(ret)) #18779264 print(id(test1)) #18779264,地址都同样,说明指向同一个内存地址 #经过引用调用函数 ret() #--- in test1 func----
def outer(num): print('outer...') def inner(): print('num=%s'%num) return inner ret = outer(100) #outer... ret() #num=100 ret() #num=100
def line_conf(a, b): def line(x): return a*x + b return line line1 = line_conf(2,3) print(line1(10)) #23 line2 = line_conf(3,4) print(line2(10)) #34
闭包的优缺点
def outer(func): print('outer...') def inner(): print('inner...') func() return inner def save(): print('save...') ret = outer(save) #outer ret() #inner... save...
def login(func): def inner(): name = input('输入用户名:') pwd = input('输入密码:') if name=='laowang' and pwd=='123': func() else: print('赶忙去登陆。。。。。。') return inner @login def save(): print('save...') save()
def makeBold(fn): print('makeBold...') def wrapped(): return "--1--" + fn() + "--1--" return wrapped def makeItalic(fn): print('makeItalic...') def wrapped(): return "--2--" + fn() + "--2--" return wrapped @makeBold @makeItalic def test(): return "hello world-test" print(test()) #结果 #makeItalic... #makeBold... #--1----2--hello world-test--2----1--
from time import ctime, sleep def timefun(func): def wrappedfunc(): print("%s called at %s"%(func.__name__, ctime())) func() return wrappedfunc @timefun def foo(): print("I am foo") foo() #foo called at Thu Jul 20 16:03:59 2017 #I am foo sleep(2) foo()
foo = timefun(foo) #foo先做为参数赋值给func后,foo接收指向timefun返回的wrappedfunc foo() #调用foo(),即等价调用wrappedfunc() #内部函数wrappedfunc被引用,因此外部函数的func变量(自由变量)并无释放 #func里保存的是原foo函数对象
def timefun(func): def wrappedfunc(a, b): print("%s called at %s"%(func.__name__, ctime())) print(a, b) func(a, b) return wrappedfunc @timefun def foo(a, b): print(a+b) foo(3,5) #foo called at Thu Jul 20 16:07:48 2017 #3 5 #8
from time import ctime, sleep def timefun(func): def wrappedfunc(*args, **kwargs): print(args) print(kwargs) print("%s called at %s"%(func.__name__, ctime())) func(*args,**kwargs) return wrappedfunc @timefun def foo(a, b, c,num): print(a+b+c) print(num) foo(3,5,7,num=123) #(3, 5, 7) #{'num': 123} #foo called at Thu Jul 20 16:11:06 2017 #15 #123
from time import ctime, sleep def timefun_arg(pre="hello"): def timefun(func): def wrappedfunc(): print("%s called at %s %s"%(func.__name__, ctime(), pre)) return func() return wrappedfunc return timefun @timefun_arg("wangcai") def foo(): print("I am foo") @timefun_arg("python") def too(): print("I am too") foo() #foo called at Thu Jul 20 16:23:48 2017 wangcai #I am foo print('************************华丽的分割线************************') too() #too called at Thu Jul 20 16:23:48 2017 python #I am too
总结:
通常状况下为了让装饰器更通用,能够有return
def haha(x): def outer(func): def inner(): if x%2==0: return func()+'八' else: return '八'+func() return inner return outer @haha(1) def laowang(): return '老王' print(laowang()) #八老王
class Test(object): def __init__(self, func): print("---初始化---") print("func name is %s"%func.__name__) self.__func = func def __call__(self): print("---装饰器中的功能---") self.__func() #说明: #1. 当用Test来装做装饰器对test函数进行装饰的时候,首先会建立Test的实例对象 # 而且会把test这个函数名当作参数传递到__init__方法中 # 即在__init__方法中的func变量指向了test函数体 # #2. test函数至关于指向了用Test建立出来的实例对象 # #3. 当在使用test()进行调用时,就至关于让这个对象(),所以会调用这个对象的__call__方法 # #4. 为了可以在__call__方法中调用原来test指向的函数体,因此在__init__方法中就须要一个实例属性来保存这个函数体的引用 # 因此才有了self.__func = func这句代码,从而在调用__call__方法中可以调用到test以前的函数体 @Test def test(): print("----test---") test() showpy()#若是把这句话注释,从新运行程序,依然会看到"--初始化--" 运行结果以下: ---初始化--- func name is test ---装饰器中的功能--- ----test---
动态编程语言是高级程序设计语言的一个类别,在计算机科学领域已被普遍应用。它是一类 在运行时能够改变其结构的语言 :例如新的函数、对象、甚至代码能够被引进,已有的函数能够被删除或是其余结构上的变化。动态语言目前很是具备活力。例如JavaScript即是一个动态语言,除此以外如 PHP 、 Ruby 、 Python 等也都属于动态语言,而 C 、 C++ 等语言则不属于动态语言。----来自维基百科
class mv_hero: def __init__(self,name,HP,MP): self.name = name self.HP = HP self.MP = MP #调用,实例化 gtx = mv_hero('cjr',10,10) print(gtx.name) #cjr #添加一个实例属性 gtx.XP = 100 print(gtx.XP) #100 #添加一个类属性 mv_hero.xx = 99 #gtx.xx = 111 print(gtx.xx) #99 #定义一个类方法 @classmethod def atteck(cls): cls.num = 100 #定义一个静态方法 @staticmethod def test_hero(): print('--test_hero--') #给mv_hero类绑定类方法 mv_hero.atteck = atteck #调用刚才绑定的类方法 mv_hero.atteck() print(mv_hero.num) #100 #给mv_hero类绑定静态方法 mv_hero.test_hero = test_hero #调用刚才绑定的静态方法 mv_hero.test_hero() #--test_hero-- import types #定义一个实例方法 def fly(self, speed): print("%s在移动, 速度是 %s"%(self.name, speed)) #给mv_hero中的对象绑定实例方法 gtx.fly = types.MethodType(fly, gtx) #调用刚才的实例方法 gtx.fly(180) #cjr在移动, 速度是 180
如今回到咱们的大主题上来,到底是为何你会去使用这样一种容易出错且晦涩的特性?好吧,通常来讲,你根本就用不上它!
''' 使用type建立类 type的第3个参数 一、字符串 类名 二、元组 父类 三、字典 类属性 ''' ''' class Test: pass ''' Test = type('Test',(),{}) print(Test) Test = type('Test',(),{'name':'老王','age':10}) print(Test.name) class Fu: def fu(self): print('fu...') Zi = type('Zi',(Fu,),{}) print(Zi.__mro__) print('***************************************华丽的分割线***************************************') def haha(self): print('haha...') def __init__(self,num): print('self...') self.num = num @classmethod def hehe(cls): print('hehe...') Test = type('Test',(),{'name':'老王','age':10,'haha':haha,'hehe':hehe,'__init__':__init__}) t = Test(110) t.haha() Test.hehe()
python建立9个”HelloWorld”对象,让他只占用一个”HelloWorld”所占的内存空间,python中有这样一个机制——intern机制,靠引用计数去维护什么时候释放。
字符串(含有空格),不可修改,没开启intern机制,不共用对象,引用计数为0,销毁。
总结
python采用的是引用计数机制为主,标记-清除和分代收集两种机制为辅的策略
map(function, sequence[, sequence, ...]) -> list ·function:是一个函数 ·sequence:是一个或多个序列,取决于function须要几个参数 ·返回值是一个列表 参数序列中的每个元素分别调用function函数 返回包含每次function函数返回值的list。 注意:先转成list才能print
>>>def square(x) : # 计算平方数 ... return x ** 2 >>> map(square, [1,2,3,4,5]) # 计算列表和:1+2+3+4+5 [1, 4, 9, 16, 25] >>> map(lambda x: x ** 2, [1, 2, 3, 4, 5]) # 使用 lambda 匿名函数 [1, 4, 9, 16, 25] # 提供了两个列表,对相同位置的列表数据进行相加 >>> map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10]) [3, 7, 11, 15, 19]
range(start, stop[, step]) -> list of integers ·start:计数从start开始。默认是从0开始。例如range(5)等价于range(0,5); ·stop:到stop结束,但不包括stop.例如:range(0,5) 是[0, 1, 2, 3, 4]没有5 ·step:每次跳跃的间距,默认为1。例如:range(0,5) 等价于range(0, 5, 1) python2中range返回列表,python3中range返回一个迭代值。若是想获得列表,可经过list函数
filter(function or None, sequence) -> list, tuple, or string ·function:接受一个参数,返回布尔值True或False ·sequence:序列能够是str,tuple,list ·返回值是一个列表
过滤出列表中的全部奇数: def is_odd(n): return n % 2 == 1 newlist = filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) print(newlist) 输出结果 : [1, 3, 5, 7, 9]
sorted()
sort 与 sorted 区别:
sort 是应用在 list 上的方法,sorted 能够对全部可迭代的对象进行排序操做。
list 的 sort 方法返回的是对已经存在的列表进行操做,而内建函数 sorted 方法返回的是一个新的 list,而不是在原来的基础上进行的操做。
sorted(iterable, key=None, reverse=False) --> new sorted list reverse默认值为False,升序排序
>>>a = [5,7,6,3,4,1,2] >>> b = sorted(a) # 保留原列表 >>> a [5, 7, 6, 3, 4, 1, 2] >>> b [1, 2, 3, 4, 5, 6, 7] >>> L=[('b',2),('a',1),('c',3),('d',4)] >>> sorted(L, cmp=lambda x,y:cmp(x[1],y[1])) # 利用cmp函数 [('a', 1), ('b', 2), ('c', 3), ('d', 4)] >>> sorted(L, key=lambda x:x[1]) # 利用key [('a', 1), ('b', 2), ('c', 3), ('d', 4)] >>> students = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)] >>> sorted(students, key=lambda s: s[2]) # 按年龄排序 [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)] >>> sorted(students, key=lambda s: s[2], reverse=True) # 按降序 [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
reduce(function, sequence[, initial]) -> value ·function:该函数有两个参数 ·sequence:序列能够是str,tuple,list ·initial:固定初始值 reduce依次从sequence中取一个元素, 和上一次调用function的结果作参数再次调用function。 第一次调用function时,若是提供initial参数, 会以sequence中的第一个元素和initial做为参数调用function, 不然会以序列sequence中的前两个元素作参数调用function。 注意function函数不能为None。
在Python3里,reduce函数已经被从全局名字空间里移除了,它如今被放置在fucntools模块里用的话要先引入:from functools import reduce
>>>def add(x, y) : # 两数相加 ... return x + y ... >>> reduce(add, [1,2,3,4,5]) # 计算列表和:1+2+3+4+5 15 >>> reduce(lambda x, y: x+y, [1,2,3,4,5]) # 使用 lambda 匿名函数 15
def f(x,y): print('x=%s,y=%s'%(x,y)) return x+y #ret = functools.reduce(lambda x, y: x+y, ['a','b','c','d'],'o') ret = functools.reduce(f, ['a','b','c','d'],'o') 运行结果: x=o,y=a x=oa,y=b x=oab,y=c x=oabc,y=d
functools 是python2.5被引人的,一些工具函数放在此包里。
知道有这么个东西
标准库 | 说明 |
---|---|
builtins | 内建函数默认加载 |
sys | 操做系统借口 |
functooks | 经常使用的工具 |
json | 编码和解码JSON对象 |
logging | 记录日志、调试 |
multiprocessing | 多进程 |
threading | 多线程 |
copy | 拷贝 |
time | 时间 |
datetime | 日期和时间 |
calendar | 日历 |
hashlib | 加密算法 |
random | 生成随机数 |
re | 字符串正则匹配 |
socket | 标准的BSD Sockets API |
shutil | 文件和目录管理 |
glob | 基于文件通配符搜索 |
更多标准库
http://python.usyiyi.cn/translate/python_352/library/index.html
在pycharm里,Ctrl+Alt+L自动排版,排版的时候注意看一看就记住了
pycharm
步骤: