Python核心编程

瘦欲@ 提交于 2020-01-02 01:09:55
  1. 模块循环导入问题
  2. 深拷贝和浅拷贝
  3. 位运算
  4. 获取私有属性的值
  5. property的使用
  6. 迭代器
  7. 闭包
  8. 装饰器
  9. python动态添加属性以及方法
  10. 生成器
 
 

1.模块循环导入问题
#vi a.py
from b import b
def a():
    print('-----a-----')
    b()
a()
#vi b.py
from a import a
def b():
    print('-----b-----')
def c():
    print('------c-----')
    a()
c()
#python3 a.py的结果是:ImportError:cannot import name 'a'
解决办法:不要互相调用,另外写个主模块去调它们(子模块)
 

2.深拷贝与浅拷贝
#浅拷贝
a = [11,22,33]
b = a
id(a) == id(b)   #True
 
#深拷贝
a = [11,22,33]
import copy
c = copy.deepcopy(a)
id(a) == id(b) #False
 
#copy与deepcopy的区别
copy只拷贝第一层引用;deepcopy是递归拷贝所有引用
当copy遇到元组时,会进行浅拷贝(只指向)
 

3.位运算
& 按位与
| 按位或
^ 按位异或
~ 按位取反
<< 按位左移
>> 按位右移
用途:直接操作二进制,省内存,效率高
按位移:
8>>1   4
8<<1   16
按位与:
全1才1否则0:只有对应的两个二进制均为1时,结果位才为1,否则为0
按位或:
有1就1 只要对应的二个二进位有一个为1时,结果位就为1,否则为0
按位异或:
不同为1 只要对应的二进位相异(不相同)时,结果为1,否则为0
取反:
~9 = -10
 

4.获取私有属性的值:
class Test(object):
    def __init__(self):
        self.__num = 100
    def setNum(self, newNum):
        self.__num = newNum #修改私有属性的值
    def getNum(self):
        return self.__num #返回私有属性的值
 
t = Test()
#print('t.__num')
#t.__num = 200
#print(t.__num)
print(t.getNum())
t.setNum(39)
print(t.getNum())
#私有化的本质是把私有属性给改名了。如_类名__num
 

5.property的使用:
class Test(object):
    def __init__(self):
        self.__num = 100
    def setNum(self, newNum):
        self.__num = newNum #修改私有属性的值
    def getNum(self):
        return self.__num #返回私有属性的值
    num = property(getNum, setNum)
t = Test()
t.num = 200 #相当于t.setNum(9)
print(t.num)
注意点:
t.num 到底是调用getNum()还是setNum(),要根据实际的场景来判断;
如果是给t.num赋值,那么一定调用setNum();
如果是获取t.num的值,那么就一定调用getNum();
property的作用:相当于把方法进行了封装,开发者在对属性设置数据的时候更方便了
#使用装饰器
class Test(object):
    def __init__(self):
        self.__num = 100
    @property
    def num(self):
        return self.__num
    @num.setter
    def num(self, newNum):
        self.__num = newNum
 
t = Test()
t.num = 200
print(t.num)
 

6.迭代器:
判断是否为Itarable类型
from collections import Iterable
a = isinstance('abv', Iterable)
print(a)
#判断是否为Iterator类型
from collections import Iterator
a = isinstance('ac', Iterator)
print(a)
使用iter()函数把Iterable变成Iterator
a = isinstance(iter('abc'), Iterator)
print(a)
 

7.闭包:
#函数里面套用函数,里面的函数用到了外面函数的参数,就叫做闭包
def test(number):
    def test2(number2):
        print('-----%s-----'%number2)
        return number+number2
    return test2 #返回函数的地址
 
ret = test(100) #ret已经记住了外部的参数
print(ret(20))
#一个闭包的实际例子
def line_conf(a, b):
    def line(x):
        return a*x + b
    return line
 
line1 = line_conf(1, 1)
line2 = line_conf(4, 5)
print(line1(5))
print(line2(5))
#函数的最终形式(y=x+!)(y=4x+5)
#1.闭包优化了变量,原来需要类对象完成的工作,闭包也可以完成
#2.由于闭包引用了外部函数的局部变量,则外部函数的局部变量没有及时释放,消耗内存
#初始设计
def function(a,b,x):
    print(a*x+b)
 
function(1,1,0)
 

8.装饰器:
#装饰器第一个版本
def base(func):
    def inner():
       print('-----装饰器-----')
       func()
    return inner
 
def a():
    print('-----a------')
 
def b():
    print('-----b------')
 
innerFunc = base(b)
innerFunc()
装饰器的第二个版本
def base(func):
    def inner():
       print('-----正在验证权限-----')
       if False:
           func()
       else:
            print('没有权限')
    return inner
@base
def a():
    print('-----a------')
@base
def b():
    print('-----b------')
 
b()
#装饰器的执行顺序,快递(装的时候是从里往外装,拆的时候从外往里拆)
#coding:utf-8
def w1(func):
    print('-----正在装饰1-----')
    def inner():
        print('-----正在验证权限1-----')
        func()
    return inner
 
def w2(func):
    print('-----正在装饰2-----')
    def inner():
        print('-----正在验证权限2-----')
        func()
    return inner
 
@w1
@w2
def f1():
    print('-----f1-----')
#有参数
def func(functionName):
    print('-----func-----1---')
    def func_in(a, b): #如果a,b没有定义,那么会导致下面的调用失败
        print('----func_in----1----')
        functionName(a, b)   #要把a, b当作实参进行传递
    print('----func----2----')
    return func_in
 
@func
def test(a, b):
    print('-----test-a=%d, b=%d-----'%(a, b))
 
test(11,22)
#不确定参数
def func(functionName):
    print('-----func-----1---')
    def func_in(*args, **kwargs): #如果a,b没有定义,那么会导致下面的调用失败
        print('----func_in----1----')
        functionName(*args, **kwargs)   #要把a, b当作实参进行传递
    print('----func----2----')
    return func_in
 
@func
def test(a, b, c):
    print('-----test-a=%d, b=%d-----'%(a, b, c))
 
@func
def test2(a, b, c, d):
    print('-----test-a=%d, b=%d, c=%d, d=%d---'%(a, b, c, d))
test(11,22,33)
test2(22,33,44,55)
#装饰器对对带有返回值的函数进行装饰
#解ret为None的bug
def func(functionName):
    print('-----func-----1---')
    def func_in():
        print('----func_in----1----')
        functionName()
    print('----func----2----')
    return func_in
 
@func
def test():
    print('-----tes-----')
    return 'haha'
ret = test()
print('test return value is %s'%ret)
#因为test()指向了func_in(),而func_in由调用了test(),而return的返回值却没有变量来接收,因此只需要找一个变量来接收functionName()的返回值就好了
#通用装饰器
def func(functionName):
    def func_in(*args, **kwargs):
        ret = functionName(*args, **kwargs)
        return ret
    return func_in
 
@func
def test():
    print('-----test1-----')
    return 'haha'
 
@func
def test2():
    print('-----test2-----')
@func
def test3(a):
    print('----test3----a=%d--'%a)
 
ret = test()
print('test return value is %s'%ret)
a = test2()
print('test2 return value is %s'%a)
test3(11)
#带有参数的装饰器
def func_arg(arg):
    def func(functionName):
        def func_in():
            print('-----记录日志--arg=%s---'%arg)
            if arg == 'heihei':
                functionName()
                functionName()
                        else:
                              functionName()
        return func_in
    return func
#1.先执行func_arg('heihei')函数,这个函数return的结果是func这个函数的引用
#2.@func
#3.使用@func对test进行装饰
#带有参数的装饰器,能够起到在运行时,有不同的功能
@func_arg('heihei')
def test():
    print('-----test-----')
 
test()
 

9.动态添加属性和方法
作用域:
什么是命名空间?
名字起作用的范围
globals
locals
LEGB规则:
找一个变量,先找局部,再找有没有闭包,再找全局变量,再找内键
#为类动态添加属性
class mate(object):
    def __init__(self, Newname, Newage):
        self.name = Newname
        self.age = Newage
laowang = mate('老王', 18)
为变量添加单一属性
laowang.addr = '北京'
print(laowang.addr)
#为类添加属性
mate.addr = '中国'
print(laowang.addr)
#为类动态添加方法
import types
class mate(object):
    def __init__(self, Newname, Newage):
        self.name = Newname
        self.age = Newage
    def eat(self):
        print('----eat----')
def run(self):
    print('-----run-----')
wang = mate('老王', 18)
wang.run = types.MethodType(run, wang)
wang.run()
#静态方法添加
@staticmethod
def test():
    print('-----static method---')
p.test = test
p.test()
__slots__方法
使用__slots__来限制class实例能添加的属性,但是仅能对当期的类添加限制,对继承的子类没有限制
__slots__ = [‘name’, ‘age’]
 

10.生成器:
第一种生成器:把列表生成式的[]变为()
a = [x*2 for x in range(10)]
a = (x*2 for x in range(10))
print(a)
next(a)
创建生成式方法二
def creatNum():
    print('-----start-----')
    a, b = 0, 1
    for i in range(5):
        print('-----1-----')
        yield b
        print('-----2-----')
        a, b = b, a+b
    print('-----stop-----')
a = creatNum()
for num in a:
    print(num)
#send的使用
def test():
    i = 0
    while i <5:
        temp = yield i
        print(temp)
        i += 1
 
t = test()
t.__next__()
t.send('haha')
第一次调用send的解决办法:
1.先用next,在用send
2.send(None),再使用send 
#多任务(协程)
def test1():
    while True:
        print('-----1-----')
        yield None
def test2():
    while True:
        print('-----2-----')
        yield None
t1 = test1()
t2 = test2()
while True:
    t1.__next__()
    t2.__next__()
 
 
 
 
 
 
 
 
 
 
 
 
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!