1. is 和 ==区别html
is 判断是不是一个ID(内存中的数据是不是同一个), == 判断内容是否一致。python
2.python 常量池包括闭包
1.短整型的-5~256app
2.字符串的数字、大小写字母随意组合(待研究)函数
3.字符串的单个符号测试
4.布尔类型的True、Falsespa
5.None命令行
6.空元组tuple线程
7.空不可变集合frozensetcode
3.在同一个做用域内的两个变量,若是赋值超出常量池的整形、字符串、浮点型,则使用同一个内存。
# 在命令行中 a = 1 b = 1 print(a is b) # True a = 257 b = 257 print(a is b) # False a = 'helloWorld' b = 'helloWorld' print(a is b) # True a = 'hello world' b = 'hello world' print(a is b) # False a = 'hello world';b = 'hello world';print(a is b) # True # 在同一个做用域中,如同一个函数内。 # 以上都是 True # a和b不在同一个函数、类、py文件中
# 结果与在命令行中的结果相同
4.可变对象与不可变对象
不可变对象:该对象所指向的内存中的值不能被改变。也就是说内存中一旦一个值占据以后,这块内存中存的数据就不会发生变化了,直到被销毁后才能够存其它值。
可变对象:该对象所指向的内存中的值能够被改变。
不可变对象类型:bool、int、float、str、tuple、frozenset
可变对象类型:list、set、dict
常量池中的数据类型都是不可变对象类型!
5.值传递与引用传递
1. 不可变对象做为函数参数,至关于C语言的值传递。
2. 可变对象做为函数参数,至关于C语言的引用传递。(因列表是可变数据类型,做为参数传递实则是传递对列表的引用,修改更新列表值后依旧引用不变)
# 值传递,value_a把本身的值传递给函数func_1的变量value_1后, # value_1的值修改了,value_a的值不会变 def func_1(value_1): print(value_1) value_1 = 2 print(value_1) value_a = 1 func_1(value_a) print(value_a) # 引用传递,list_a把引用传递给函数func_2的变量list_1后, # 修改list_1的值,list_a的值也发生的改变。 # 因此,若是list_a要再给别的函数传的话,就是func_2修改后的值 def func_2(list_1): list_a[0] = 2 print(list_1) list_a = [1, 2] func_2(list_a) print(list_a) # 引用传递,当第一次调用func_3时,因为没有入参,默认从内存开辟 # 一块空间将一个空列表放进去,而后传给list_2。当list_2修改后 # 空间中的值发生变化。第二次调用func_3的时候,将第一次开辟空间的引用传给了 # list_2,因此第二次的list_2有两个hello。若是是3个线程的话,若是每一个线程里面 # 循环添加100个hello,当线程结束时list_2的值多是100到300个hello。 def func_3(list_2=[]): list_2.append('hello') print(list_2) func_3() func_3()
6.深拷贝与浅拷贝
浅拷贝:内存中的值只有一份,建立一个新的引用,指向这个内存,将新引用传递给新对象。
深拷贝:将内存中的值拷贝一份,开辟一个新空间存进去,将新空间的引用传递给新对象。
浅拷贝的目的:节约内存。
深拷贝的目的:防止变量a的值修改时,影响变量b的值。
深拷贝是针对对可变对象的,不可变对象不适用,由于不可变量的值不会改变。若是变量a的值是个不可变对象,当变量a修改时他的引用指向了新的内存地址。
import copy a = [1, 2] b = a # 赋值操做是浅拷贝 print('a_id=%s, b_id=%s, b_value=%s' % (id(a), id(b), b)) a[0] = 'a' print('a_id=%s, b_id=%s, b_value=%s' % (id(a), id(b), b)) # 变量a修改时影响了变量b a = [1, 2] b = copy.deepcopy(a) # b=a[:]也是深拷贝 print('a_id=%s, b_id=%s, b_value=%s' % (id(a), id(b), b)) a[0] = 'a' print('a_id=%s, b_id=%s, b_value=%s' % (id(a), id(b), b)) # 当a修改时不会影响b a = 'hello wold' b = copy.deepcopy(a) print('a_id=%s, b_id=%s, b_value=%s' % (id(a), id(b), b)) # 由于a是不可变对象,因此即便深拷贝也不用开辟新空间,因此ab的id相同 a = 'hello agu' print('a_id=%s, b_id=%s, b_value=%s' % (id(a), id(b), b)) # 当a修改后a的引用指向了新的内存空间,因此a的id改变了
7.私有化与property
class Secret(object): __name = 'yoda' # 加上双下划线私有化特性 def get_name(self): return self.__name def __secret(self): # 私有化方法 print "can't find" def access(self): return self.__secret() # 访问器访问私有方法 A2 = Secret() print A2.__name # 访问不到特性! 要抛异常 print A2._Secret__name # 仍是能够从外部访问特性 A2.__secret() # 访问不到特性! 要抛异常 A2._Secret__secret()
# 第一种方法使用属性 class Foo(object): def __init__(self): self.name = 'yoda' self.work = 'master' def get_person(self): return self.name, self.work def set_person(self, value): self.name, self.work = value person = property(get_person, set_person) # 建立一个新属性person A3 = Foo() print A3.person # 输出:('yoda', 'master') A3.person = 'skylaer', 'programer' # A3.set_person(('skylaer', 'programer111')) # 入参必须元组 print A3.person # 输出:('skylaer', 'programer')
# 第二种方法使用属性 class Foo: def __init__(self): self.name = 'yoda' self.work = 'master' @property def person(self): return self.name, self.work @person.setter # 若是不指定stter属性,那么没法从类的外部对它的值进行设置,这对于只读特性很是有用 def person(self, value): self.name, self.work = value A3 = Foo() print(A3.person) A3.person = 'skylaer', 'programer' print(A3.person)
8.列表生成式
range(1,100,5) # 第一个参数表示开始位,第二个参数表示结束位(不含),第三个参数表示步长,就是每5个数返回一次。 a = [i for i in range(1,10)] # 列表生成式表示返回i的值,而且返回9次,每次返回的是i的值。 a = [2 for i in range(1,10)] # 这里表示返回2,而且返回9次,可是每次的值都是2。 a = [i for i in range10 if i%2==0] #表示在生成式内部加入if判断,当i除以2的余数等于0的时候将数值返回。 a = [(i,j) for i in range(5) for j in range(5)] #表示将i和j的值以元组为元素的形式返回,当i循环一次的时候j循环5次,以此类推
9.生成器
def num(): """ 1.生成器关键字yield,有yield的关键字的代码块就是yield的生成器 2.生成器不能够return 3.执行next时程序运行到yield行等号右边的时候就会中止, 当在次使用next的时候,将会把一个None赋值给temp,由于b的值已经在上轮循环中输出。 4.使用num().send()方法会将一个新的值赋值给temp,而后接着执行一个next """ value = 0 for i in range(6): value += 1 print('num: before yield') temp = yield value # print('num: after yield temp=%s' % temp) # next时,今后处开始,而后判断for有无结束 a = num() # 将生成器赋值给变量a。 print('---- start test ----') rst = next(a) print('---- rst=%s ----\n' % rst) rst = next(a) print('---- rst=%s ----\n' % rst) rst = a.send('666') # send时num生成器会把666赋值给temp,而后接着执行一个next print('---- after send rst=%s----\n' % rst) rst = next(a) print('---- rst=%s ----\n' % rst) i = 1000 for n in a: # 生成器可使用for循环使用,而且不会出错。 print('call: before send, n=%s' % n) a.send(i) print('call: after send') i += 1
10.迭代器
# for i in '',[],(),{},{:} # 能够for循环的对象是可迭代对象。 a = (i for i in range(100)) # 列表生成式,把中括号改成小括号就能够变为一个列表生成器,是可迭代对象。 from collections import Iterable # 若是想验证是不是可迭代对象,可使用isinstance()判断是不是可迭代对象。 isinstance('abc', Iterable) # 判断语法 a = [1, 2, 3, 4, 5] b = iter(a) # 使用iter()方法能够将可迭代的对象转换为可迭代对象。
11.闭包
def num(num): # 定义函数 def num_in(num_2): # 定义函数 return num + num_2 # 返回两个参数的和。 return num_in # 返回内部函数的引用。(变量名) a = num(100) # 将参数为100的函数num接收,并赋值给a,只不过这个返回值是一个函数的引用。等于 a = num_in,注意这里接收的不光是函数自己,还有已经传递的参数。 b = a(100) # 调用函数a,即num_in,并传递一个参数100,返回值给b。 print(b)
12.装饰器
def wraps(func): # 定义了一个闭包 def func_in(): # 闭包内的函数 print('这里是须要装饰的内容,就是须要添加的内容') func() # 调用实参函数。 return func_in def test(): # 须要被装饰修改的函数。 print('无参函数的测试') test = wraps(test) # 装饰器的原理就是将原有的函数名从新定义为以原函数为参数的闭包。 test() # 这里再次掉用test()的时候,实际上是将会调用闭包内的函数func_in()。因此将会起到装饰修改的做用,最后会再次调用原函数test()。 @wraps # 装饰器的python写法,等价于test = function(test),而且无需调用当代码运行道这里,Python会自动运行。 def test(): print('无参函数的测试') test() # 这里再次调用函数时,将会产生修改后的效果。
def wraps(func): # 定义了一个闭包 def func_in(*args, **kwargs): # 闭包内的函数,由于装饰器运行的实则是闭包内的函数,因此这里将须要有形参用来接收原函数的参数。 print('这里是须要装饰的内容,就是须要添加的内容: %s' % str(args)) a, b = args a += 10 b += 10 func(a, b) # 调用实参函数,并传入一致的实参。 return func_in @wraps # 装饰器的python写法,等价于test = function(test) . def test(a, b): print('a+b=%s' % (a+b)) test(1, 1) # 这里再次掉用test()的时候,实际上是将会调用闭包内的函数func_in()。因此将会起到装饰修改的做用,最后会再次调用原函数test()。
def wraps(func): # 定义了一个闭包 def func_in(*args, **kwargs): # 由于装饰器运行的实则是闭包内的函数,因此这里将须要有形参用来接收原函数的参数。 print('这里是须要装饰的内容,就是须要添加的内容') num = func(*args, **kwargs) # 调用实参函数,并传入一致的实参,而且用变量来接收原函数的返回值, return num # 将接受到的返回值再次返回到新的test()函数中。 return func_in @wraps def test(a, b): # 定义一个函数 return a + b # 返回实参的和 print(test(1, 1))
def outer(number): def wraps(func): # 定义了一个闭包 def func_in(a, b): # 闭包内的函数 a += number b += number num = func(a, b) # 调用实参函数,并传入一致的实参,而且用变量来接收原函数的返回值, return num # 将接受到的返回值再次返回到新的test()函数中。 return func_in return wraps @outer(100) # 这里会先运行函数wraps,传入参数,以后会再次运行闭包函数进行装饰。 def test(a, b):return a + b print(test(1, 1))
class Test(object): # 定义一个类 def __init__(self, func): self.__func = func def __call__(self): # 定义call方法,当直接调用类的时候,运行这里。 print('这里是装饰的功能') self.__func() @Test # 类装饰器等于test = Test(test),将函数test看成参数传入类中的init方法,并将函数名赋值给私有属性__func,当函数test被调用的时候,实际上是运行Test类中的call方法. def test(): print('被装饰的函数') test() # 这里调用的不在是函数test,而是实例对象test的call方法,会先进行装饰,而后再调用私有属性__func(),__func 其实就是被装饰的函数test。
def outer(clss): # 类装饰器 class Inner(object): def __init__(self): print('inner init') self.clss = clss() def __getattr__(self, attr): return getattr(self.clss, attr) return Inner @outer # Zoo = outer(Zoo) class Zoo(object): def __init__(self): pass def say(self): print('hello world!') zoo = Zoo() print(zoo.__class__) zoo.say()
13. 动态添加属性和方法
class Person(object): # 建立一个类 def __init__(self, name): # 定义初始化信息。 self.name = name li = Person('李') # 实例化Person('李'),给变量li li.age = 20 # 再程序没有中止下,将实例属性age传入。动态语言的特色。 Person.age = None # 这里使用类名来建立一个属性age给类,默认值是None。Python支持的动态属性添加。 def eat(self): # 定义一个方法,不过这个方法再类以外。 print('%s正在吃东西。。' % self.name) import types # 动态添加方法须要使用tpyes模块。 li.eat = types.MethodType(eat, li) # 使用types.MethodType,将函数名和实例对象传入,进行方法绑定。而且将结果返回给li.eat变量。实则是使用一个和li.eat方法同样的变量名用来调用。 li.eat() # 调用外部方法eat()方法。 @staticmethod # 定义静态方法。 def test(): # 定义静态方法,静态方法能够不用self参数。 print('这是一个静态方法。') Person.test = test # 使用类名.方法名 = test的形式来方便记忆和使用,Person.test其实只是一个变量名,没有特殊的含义。 Person.test() # 调用test方法。 @classmethod # 类方法 def test(cls): print('这是一个类方法。') Person.test = test # 定义一个类属性等于方法名。 Person.test() # 调用方法。 class test(object): # 定义一个类。 __slots__ = ('name', 'age') # 使用slots来将属性固定,不能进行动态添加修改。
14.元类
# 元类是只使用type建立的类,使用type会有3个参数,第一个是类名,第二个小括号内是父类名,须要使用元组。 # 第三个字典中是类属性,使用type可以快速的动态建立一个类。 Test = type('Test', (object,), {'num': 0}) class Test(object): # 建立一个类,等价于上边 num = 0 def eat(self): # 定义一个函数,self做为第一个参数。 print ('%s正在吃饭。。' % self.name) # 使用type建立一个类,可是有两个属性,一个是eat,一个是name,可是eat的值是函数eat的引用。 Person = type('Person', (object,), {'eat': eat, 'name': None})
15.内建属性
__init__ #构造初始化函数,__new__以后运行 __new__ #建立实例所需的属性 __class__ #实例所在的类,实例.__class__ __str__ #实例的字符串表示,可读性高 __repr__ #实例的字符串表示,准确性高 __del__ #删除实例引用 __dict__ #实力自定义属性,vars(实例.__dict__) __doc__ #类文档,help(类或者实例) __bases__ #当前类的全部父类 __getattribute__ #属性访问拦截器。
16.内建方法
range(start,stop,[,step]) #生成器 map(function, iterable, ...) # map() 会根据提供的函数对指定序列作映射。 filter(function, iterable) #filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。 reduce(function, iterable[, initializer]) #reduce() 函数会对参数序列中元素进行累积。 sorted(iterable[, cmp[, key[, reverse]]]) #sorted() 函数对全部可迭代的对象进行排序操做。sort 与 sorted 区别: sort 是应用在 list 上的方法,sorted 能够对全部可迭代的对象进行排序操做。 list 的 sort 方法返回的是对已经存在的列表进行操做,而内建函数 sorted 方法返回的是一个新的 list,而不是在原来的基础上进行的操做。