美文网首页
十个经验点总结(2)

十个经验点总结(2)

作者: ZzzZBbbB | 来源:发表于2019-03-19 14:27 被阅读0次
    • 字符串的驻留(string interning)
      由于 Cpython 在编译优化时, 某些情况下会尝试使用已经存在的不可变字符串对象而不是每次都创建一个新对象,由此节省大量内存
      字符串的驻留一些常见的规则:
      >>> a ='helloworld'
      >>> a is (''.join(['h','e','l','l','o','w','o','r','l','d']))
      False  #运行的时候不驻留
      >>> a = 'hello'+'world'
      >>> b = 'helloworld'
      >>> a is b #编译时候驻留
      True
    
      >>> a = ''
      >>> b = ''
      >>> a is b
      True #字符串长度为0或者1的时候默认驻留
    
      >>> a = 'helloworld_'
      >>> b ='helloworld_'
      >>> a is b
      True
      >>> a = 'hello~~'
      >>> b = 'hello~~'
      >>> a is b
      False # 字符串>1时,且只含大小写字母、数字、下划线时,才会默认驻留
    
      >>> a,b,c,d = -6,-5,256,257
      >>> e,f,g,h  = -6,-5,256,257
      >>> a is e
      False
      >>> b is f
      True
      >>> c is g
      True
      >>> d is h
      False  # 对于[-5,256]之间的整数数字,Python默认驻留
    
      >>> from sys import intern
      >>> a = intern('~!@#$%^&*')
      >>> b = intern('~!@#$%^&*')
      >>> a  is b  
      True  #可以通过显示驻留的方式使得两个变量引用同一个字符串
    
      >>> 'a' * 20 is 'aaaaaaaaaaaaaaaaaaaa'
      True
      >>> 'a' * 21 is 'aaaaaaaaaaaaaaaaaaaaa'
      False  # 常量折叠(constant folding) 在编译时表达式 'a'*10 会被替换为 'aaaaaaaaaa' 
      #来减少运行时的时钟周期. 长度小于20的字符串才会发生常量折叠,默认驻留
      >>> a, b = 'hello!', 'hello!'
      >>> a is b 
      True # 这里虽然有!字符,但是a,b的变量赋值在同一行, 
      #Python 解释器会创建一个新对象, 然后同时引用第二个变量,这是是一种编译器优化, 适用于交互式环境.
      >>> a = 'hello!'
      >>> b = 'hello!'
      >>> a is b 
      Fasle
    

    • *args 和 **kwargs :不定长参数
      用途:函数定义,使得函数能处理比当初声明时更多的参数。
      *args 用来发送一个非键值对的可变数量的参数列表给一个函数;
      **kwargs 允许将不定长度的键值对, 作为参数传递给一个函数;
      通俗来说 , *args 传入列表 *kwargs 传入字典
      注意标准参数在使用时候的顺序some_func(fargs, *args, **kwargs) # 记得加上*和**
    def fun_1(a,b,*args,**kwargs):
        print('a=',a)
        print('b=',b)
        print('arg=',args)
        print('kwargs=',kwargs)
    a = 1
    b = 2
    c = (3,4,5)
    d = {"m":6, "n":7, "p":8}
    
    fun(1, 2, *c, **d) 
    #输出
    a= 1
    b= 2
    arg= (3, 4, 5)
    kwargs= {'m': 6, 'n': 7, 'p': 8}
    
    fun(1, 2, c, d) #  注意不加*的区别
    #输出
    a= 1
    b= 2
    arg= ((3, 4, 5), {'m': 6, 'n': 7, 'p': 8})
    kwargs= {}
    

    • 多重赋值技巧: 将一个列表中的各项分别赋值给多个变量
    dog = ['Retriever', 'yellow', 'kind'] 
    variety, color, disposition = dog
    

    • 浮点数的不精确性
      >>> a = 1.1
      >>> b = 2.2
      >>> a+b == 3.3
      False
      >>> a + b
      3.3000000000000003
     
      from decimal import Decimal   #decimal 模块为快速正确舍入的十进制浮点运算提供支持
      a = Decimal(‘1.1’) 
      b = Decimal(‘2.2’)            
      a+b == Decimal(‘3.3’)   # True
    

    • 关于字典,了解这些函数代码更高效 get, clear & del , __contains__
      #不确定字典中是否存在某个键而又想获取其值时,可以使用get方法
      >>> person_info = {'name':'Sonder','sex':'male'}
      >>> nickname = person_info['nickname']   #直接获取不存在的key,会报错
      Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      KeyError: 'nickname'
      >>> like = person_info.get('like') #使用get方法获取到空的内容,不会出现异常
      >>> print(like)
      None
      >>> age = person_info.get('age',20)    #第二个参数为缺省值,即若key不存 
     在,返回该缺省值
      >>> age
      20
    
      >>> person_info.clear() #字典的清空,这里指的是删除字典里面的内容
      >>> person_info
      {}
      >>> del person_info #字典的删除 ,这里连字典的内存一并清空了 
      # 也可以del person[key]  删除某个key
      >>> person_info
      Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      NameError: name 'person_info' is not defined
    
      >>> person_info.__contains__('name') #是否包含某一个关键字
      True
    

    • 变量在计算机内存中的分配
      理解变量在计算机内存中的表示也非常重要 a = 10000
      Python解释器干了两件事情: 也就是说在内存里面创建了两个实体
    1. 在内存中创建了一个10000的整数;
    2. 在内存中创建了一个名为a的变量,并把它指向10000
      理解:在计算机内部,可以把任何数据都看成一个“对象”,而变量就是在程序中用来指向这些数据对象的,对变量赋值就是把数据和变量给关联起来。
      >>> a = 10000
      >>> id(a)
      4405445840
      >>> id(10000)
      4405445424
      
      >>> b = 256   
      >>> id(b)
      4403553600
      >>> id(256)
      4403553600   #思考一下为什么一样? 提示:驻留
    
      >>> id('hello world')
      4407311216
      >>> a = 'hello world'
      >>> id(a)
      4407311216  #思考一下为什么一样?  #提示:内存释放
      >>> id( 'hello world')  
      4407311280  #思考一下为什么又不一样?   #提示:驻留
    

    • 构建软件设计的方法有两种:一种方法是使其简单到没有明显的缺陷;另一种方法是使其复杂到没有明显的缺陷。—— C. A. R. Hoare
      票友们:听到了吗?要么就将代码写的谁都看不懂!要么就将代码写的谁都看得懂!💪💪

    • python的变量解析原则: L->E->G->B (就近原则)
      Local:本地作用域
      Enclosing:上一层函数的作用域
      Global:全局作用域
      Bulit-in:内置作用域
    关于E的解释
    def fun_1():
        a = 1
        def fun_2():
            print(a)
        fun_2()
    fun_1()
    #打印 1
    

    • 连接字符串特别是大规模的字符串,最好用join而不是+

    若要连接字符串str1+str2+...,由于字符串是不可变的对象,执行一次就要申请一块新的内存,这样的话在n个字符串连接的过程中,会产生n-1个中间结果,每产生一个中间结果就要申请一次内存,这样会严重影响执行效率.而join不一样,它是一次性申请总的内存,然后把字符串里面的每一个元素复制到内存中去,所以join会快很多.

    #一个简单的比较查看
    import time
    t1 = time.time()
    longstr_list = ['there is a long string' for n in range(1,10000000)]
    a = ''.join(longstr_list)
    t2 = time.time()
    print('time spent:{}s by using "join"'.format(t2-t1))
    #time spent:0.612886905670166s by using "join"
    
    def add(str_list):
        b = ''
        for _ in str_list:
            b = b+_
        return b
    t1 = time.time()
    longstr_list = ['there is a long string' for n in range(1,10000000)]
    b = add(longstr_list)
    t2 = time.time()
    print('time spent:{}s by using "+"'.format(t2-t1))
    #time spent:2.0592610836029053s by using "+"
    

    *import this彩蛋
    等等, this 是什么? this 是爱 ❤️

    import this 
    >>> love = this
    >>> this is love
    True
    >>> love is True
    False
    >>> love is False
    False
    >>> love is not True or False
    True
    >>> love is not True or False; love is love  # 爱是难言的
    True
    
    # 摘抄自https://github.com/leisurelicht/wtfpython-cn 这一个纯粹是觉得好玩
    

    ~~~
    明晰你的问题,当问题真正得到定义时,问题已经解决了一半。
    ~~~

    相关文章

      网友评论

          本文标题:十个经验点总结(2)

          本文链接:https://www.haomeiwen.com/subject/kcrcpqtx.html