• Python 知识点


    1.Python自省
    2.
    单下划线和双下划线
    3.if __name__=="__main__": 是干嘛用的
    4.Python里的拷贝
    5.*args and **kwargs

    Python自省

    这个也是python彪悍的特性.

    自省就是面向对象的语言所写的程序在运行时,所能知道对象的类型.简单一句就是运行时能够获得对象的类型.

    比如type(),dir(),getattr(),hasattr(),isinstance().

     Python中单下划线和双下划线

    >>> class MyClass():
    ...     def __init__(self):
    ...             self.__superprivate = "Hello"
    ...             self._semiprivate = ", world!"
    ...
    >>> mc = MyClass()
    >>> print mc.__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内部的名字,用来区别其他用户自定义的命名,以防冲突.

    _foo:一种约定,用来指定变量私有.程序员用来指定私有变量的一种方式.

    __foo:这个有真正的意义:解析器用_classname__foo来代替这个名字,以区别和其他类相同的命名.

    双下划线开头双下划线结尾的是一些 Python 的“魔术”对象,如类成员的 __init__、__del__、__add__、__getitem__ 等,以及全局的 __file__、__name__ 等。
    Python 官方推荐永远不要将这样的命名方式应用于自己的变量或函数,而是按照文档说明来使用。
     

    if __name__ == "__main__":是干嘛的?

    # Threading example
    import time, thread
    
    def myfunction(string, sleeptime, lock, *args):
        while 1:
            lock.acquire()
            time.sleep(sleeptime)
            lock.release()
            time.sleep(sleeptime)
    if __name__ == "__main__":
        lock = thread.allocate_lock()
        thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
        thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))
    

    还有*args在这里是什么意思?


    当Python解析器读取一个源文件时,它会执行所有的代码.在执行代码前,会定义一些特殊的变量.例如,如果解析器运行的模块(源文件)作为主程序,它将会把__name__变量设置成"__main__".如果只是引入其他的模块,__name__变量将会设置成模块的名字.

    假设下面是你的脚本,让我们作为主程序来执行:

    python threading_example.py
    

    当设置完特殊变量,它就会执行import语句并且加载这些模块.当遇到def代码段的时候,它就会创建一个函数对象并创建一个名叫myfunction变量指向函数对象.接下来会读取if语句并检查__name__是不是等于"__main__",如果是的话他就会执行这个代码段.

    这么做的原因是有时你需要你写的模块既可以直接的执行,还可以被当做模块导入到其他模块中去.通过检查是不是主函数,可以让你的代码只在它作为主程序运行时执行,而当其他人调用你的模块中的函数的时候不必执行.

     Python里的拷贝

    引用和copy(),deepcopy()的区别

    import copy
    a = [1, 2, 3, 4, ['a', 'b']]  #原始对象
    
    b = a  #赋值,传对象的引用
    c = copy.copy(a)  #对象拷贝,浅拷贝
    d = copy.deepcopy(a)  #对象拷贝,深拷贝
    
    a.append(5)  #修改对象a
    a[4].append('c')  #修改对象a中的['a', 'b']数组对象
    
    print 'a = ', a
    print 'b = ', b
    print 'c = ', c
    print 'd = ', d
    
    输出结果:
    a =  [1, 2, 3, 4, ['a', 'b', 'c'], 5]
    b =  [1, 2, 3, 4, ['a', 'b', 'c'], 5]
    c =  [1, 2, 3, 4, ['a', 'b', 'c']]
    d =  [1, 2, 3, 4, ['a', 'b']]

    *args and **kwargs

    *args**kwargs只是为了方便并没有强制使用它们.

    当你不确定你的函数里将要传递多少参数时你可以用*args.例如,它可以传递任意数量的参数:

    >>> def print_everything(*args):
            for count, thing in enumerate(args):
    ...         print '{0}. {1}'.format(count, thing)
    ...
    >>> print_everything('apple', 'banana', 'cabbage')
    0. apple
    1. banana
    2. cabbage

    相似的,**kwargs允许你使用没有事先定义的参数名:

    >>> def table_things(**kwargs):
    ...     for name, value in kwargs.items():
    ...         print '{0} = {1}'.format(name, value)
    ...
    >>> table_things(apple = 'fruit', cabbage = 'vegetable')
    cabbage = vegetable
    apple = fruit

    你也可以混着用.命名参数首先获得参数值然后所有的其他参数都传递给*args**kwargs.命名参数在列表的最前端.例如:

    def table_things(titlestring, **kwargs)
    

    *args**kwargs可以同时在函数的定义中,但是*args必须在**kwargs前面.

    当调用函数时你也可以用***语法.例如:

    >>> def print_three_things(a, b, c):
    ...     print 'a = {0}, b = {1}, c = {2}'.format(a,b,c)
    ...
    >>> mylist = ['aardvark', 'baboon', 'cat']
    >>> print_three_things(*mylist)
    
    a = aardvark, b = baboon, c = cat

    就像你看到的一样,它可以传递列表(或者元组)的每一项并把它们解包.注意必须与它们在函数里的参数相吻合.当然,你也可以在函数定义或者函数调用时用*.

    
    
  • 相关阅读:
    mybaits源码分析--事务管理(八)
    mybaits源码分析--binding模块(五)
    mybaits源码分析--自定义插件(七)
    mybaits源码分析--缓存模块(六)
    2021年9月
    golang-reflect实战ini配置文件
    ECC加密原理详解
    RFID 随手记
    计算机实现加法
    公钥加密算法 RSA
  • 原文地址:https://www.cnblogs.com/touch-skyer/p/6369218.html
Copyright © 2020-2023  润新知