• python学习总结---学习交流群里的问题总结


    xml里面的过滤:

       <record id="action_partner_supplier_form_demo_ms" model="ir.actions.act_window" >
                 <field name="name">制衣供应商</field>
                 <field name="type">ir.actions.act_window</field>
                 <field name="res_model">res.partner</field>
                 <field name="view_type">form</field>
                 <field name="view_mode">kanban,tree,form</field>
                 <field name="domain">[('supple_type_categ','=',1)]</field>
                 <field name="context">{'search_default_supplier': 1,'default_customer': 0,'default_supplier': 1,'default_supple_type_categ': 1}</field>
                 <field name="view_id" ref="view_partner_form_ref"/>
            </record>

    连续添加数据到明细:

     
    def _get_sale_total(self,cr,uid,ids,field_name, arg, context=None):
    res = {}
    for order in self.browse(cr, uid, ids, context=context):
    val=0.0
    for promateline in order.line_id:
    val +=promateline.discount_tax
    res[order.id]=val
    return res



    def
    onchange_product_id(self, cr, uid,ids, product_id,line_id, context=None): result={} if product_id: sql="select product_id, sum (qty) qty,lot_id ,max(in_date) in_date ,location_id from stock_quant where product_id=%d GROUP by product_id,lot_id ,location_id;"%(product_id) cr.execute(sql) dict=cr.dictfetchall()
    # 这一句将原开数据,一直叠加进去 line_ids
    =line_id num=len(dict) i=0 for i in range(num): line_ids.append(({ 'sequence':i+1, 'product_id':dict[i]['product_id'], 'lot_id':dict[i]['lot_id'], 'wl_qty':dict[i]['qty'], 'realy_qty':dict[i]['qty'], 'date_in':dict[i]['in_date'], 'location_id':dict[i]['location_id'], })) i+=1 result['line_id']=line_ids return {'value':result}

    做odoo一年多了,今天碰到学习交流群里的一些问题:这里将它记录下来

    当函数的参数不确定时,可以使用*args 和**kwargs,*args 没有key值,**kwargs有key值。

    def fun_var_args(farg, *args): 
        print "arg:", farg 
        for value in args: 
            print "another arg:", value 
     
    fun_var_args(1, "two", 3) # *args可以当作可容纳多个变量组成的list 
    result:
    [python] 
    arg: 1 
    another arg: two 
    another arg: 3 
    **kwargs:
    [python] 
    def fun_var_kwargs(farg, **kwargs): 
        print "arg:", farg 
        for key in kwargs: 
            print "another keyword arg: %s: %s" % (key, kwargs[key]) 
     
     
    fun_var_kwargs(farg=1, myarg2="two", myarg3=3) # myarg2和myarg3被视为key, 感觉**kwargs可以当作容纳多个key和value的dictionary 
    result:
    [python] 
    arg: 1 
    another keyword arg: myarg2: two 
    another keyword arg: myarg3: 3 
    也可以用下面的形式:
    [python] 
    def fun_var_args_call(arg1, arg2, arg3): 
        print "arg1:", arg1 
        print "arg2:", arg2 
        print "arg3:", arg3 
     
    args = ["two", 3] #list
    fun_var_args_call(1, *args) 
    result:
    [python] 
    arg1: 1 
    arg2: two 
    arg3: 3 

    #这里的**kwargs可以是字典类型参数

    #简单的例子

    [python] 
    def fun_var_args_call(arg1, arg2, arg3): 
        print "arg1:", arg1 
        print "arg2:", arg2 
        print "arg3:", arg3 
     #命名变量
    kwargs = {"arg3": 3, "arg2": "two"} # dictionary 
     

    #调用函数
    fun_var_args_call(1, **kwargs) 
    result:
    [python] view plaincopyprint?
    arg1: 1 
    arg2:"two" 
    arg3:3







    python中的单例模式:

    单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。

    实现单例模式的几种形式:

    1.使用模块

    其实,Python 的模块就是天然的单例模式

    模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,

    而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了

    mysingleton.py

    class Singleton(object):
        def foo(self):
            pass
    singleton = Singleton()

    将上面的代码保存在文件 mysingleton.py 中,要使用时,直接在其他文件中导入此文件中的对象,这个对象即是单例模式的对象

    调用时用:   from a import singleton



    2.使用装饰器

    
    
    复制代码
    
    
    def Singleton(cls):
        _instance = {}
    
        def _singleton(*args, **kargs):
            if cls not in _instance:
                _instance[cls] = cls(*args, **kargs)
            return _instance[cls]
    
        return _singleton
    
    #运行时,会现加载他
    @Singleton
    class A(object):
        a = 1
    
        def __init__(self, x=0):
            self.x = x
    
    
    a1 = A(2)
    a2 = A(3)




    
    

    3.使用类

    
    
    复制代码
    
    
    class Singleton(object):
    
        def __init__(self):
            pass
    
        @classmethod   #类方法   当不知道有多个参数情况下,可以用(cls, *args, **kwargs):
        def instance(cls, *args, **kwargs):
            if not hasattr(Singleton, "_instance"):
                Singleton._instance = Singleton(*args, **kwargs)
            return Singleton._instance

    一般情况,大家以为这样就完成了单例模式,但是这样当使用多线程时会存在问题

    
    
    
    
    
    复制代码
    class Singleton(object):
    
        def __init__(self):
            pass
    
        @classmethod
        def instance(cls, *args, **kwargs):
            if not hasattr(Singleton, "_instance"):
                Singleton._instance = Singleton(*args, **kwargs)
            return Singleton._instance
    
    import threading
    
    def task(arg):
        obj = Singleton.instance()
        print(obj)
    
    for i in range(10):
        t = threading.Thread(target=task,args=[i,])
        t.start()
    复制代码
    
    

    程序执行后,打印结果如下:

    
    
    复制代码
    <__main__.Singleton object at 0x02C933D0>
    <__main__.Singleton object at 0x02C933D0>
    <__main__.Singleton object at 0x02C933D0>
    <__main__.Singleton object at 0x02C933D0>
    <__main__.Singleton object at 0x02C933D0>
    <__main__.Singleton object at 0x02C933D0>
    <__main__.Singleton object at 0x02C933D0>
    <__main__.Singleton object at 0x02C933D0>
    <__main__.Singleton object at 0x02C933D0>
    <__main__.Singleton object at 0x02C933D0>
    复制代码
    
    

    看起来也没有问题,那是因为执行速度过快,如果在init方法中有一些IO操作,就会发现问题了,下面我们通过time.sleep模拟

    
    

    我们在上面__init__方法中加入以下代码:

    
    
        def __init__(self):
            import time
            time.sleep(1)
    
    

    重新执行程序后,结果如下

    
    
    复制代码
    <__main__.Singleton object at 0x034A3410>
    <__main__.Singleton object at 0x034BB990>
    <__main__.Singleton object at 0x034BB910>
    <__main__.Singleton object at 0x034ADED0>
    <__main__.Singleton object at 0x034E6BD0>
    <__main__.Singleton object at 0x034E6C10>
    <__main__.Singleton object at 0x034E6B90>
    <__main__.Singleton object at 0x034BBA30>
    <__main__.Singleton object at 0x034F6B90>
    <__main__.Singleton object at 0x034E6A90>
    复制代码
    
    

    问题出现了!按照以上方式创建的单例,无法支持多线程

    
    
    
    
    

    解决办法:加锁!未加锁部分并发执行,加锁部分串行执行,速度降低,但是保证了数据安全

    
    
    复制代码
    import time
    import threading
    class Singleton(object):
        _instance_lock = threading.Lock()
    
        def __init__(self):
            time.sleep(1)
    
        @classmethod
        def instance(cls, *args, **kwargs):
            with Singleton._instance_lock:
                if not hasattr(Singleton, "_instance"):
                    Singleton._instance = Singleton(*args, **kwargs)
            return Singleton._instance
    
    
    def task(arg):
        obj = Singleton.instance()
        print(obj)
    for i in range(10):
        t = threading.Thread(target=task,args=[i,])
        t.start()
    time.sleep(20)
    obj = Singleton.instance()
    print(obj)
    复制代码
    
    
    
    
    

    打印结果如下:

    
    
    复制代码
    <__main__.Singleton object at 0x02D6B110>
    <__main__.Singleton object at 0x02D6B110>
    <__main__.Singleton object at 0x02D6B110>
    <__main__.Singleton object at 0x02D6B110>
    <__main__.Singleton object at 0x02D6B110>
    <__main__.Singleton object at 0x02D6B110>
    <__main__.Singleton object at 0x02D6B110>
    <__main__.Singleton object at 0x02D6B110>
    <__main__.Singleton object at 0x02D6B110>
    <__main__.Singleton object at 0x02D6B110>
    复制代码
    
    

    这样就差不多了,但是还是有一点小问题,就是当程序执行时,执行了time.sleep(20)后,下面实例化对象时,此时已经是单例模式了,但我们还是加了锁,这样不太好,再进行一些优化,把intance方法,改成下面的这样就行:

    
    
    复制代码
        @classmethod
        def instance(cls, *args, **kwargs):
            if not hasattr(Singleton, "_instance"):
                with Singleton._instance_lock:
                    if not hasattr(Singleton, "_instance"):
                        Singleton._instance = Singleton(*args, **kwargs)
            return Singleton._instance
    复制代码
    
    

    这样,一个可以支持多线程的单例模式就完成了

    import time
    import threading
    class Singleton(object):
        _instance_lock = threading.Lock()

        def __init__(self):
            time.sleep(1)

        @classmethod
        def instance(cls, *args, **kwargs):
            if not hasattr(Singleton, "_instance"):
                with Singleton._instance_lock:
                    if not hasattr(Singleton, "_instance"):
                        Singleton._instance = Singleton(*args, **kwargs)
            return Singleton._instance


    def task(arg):
        obj = Singleton.instance()
        print(obj)
    for i in range(10):
        t = threading.Thread(target=task,args=[i,])
        t.start()
    time.sleep(20)
    obj = Singleton.instance()
    print(obj)
    
    

    这种方式实现的单例模式,使用时会有限制,以后实例化必须通过 obj = Singleton.instance()

    
    

    如果用 obj=Singleton() ,这种方式得到的不是单例

    
    

    4.基于__new__方法实现(推荐使用,方便)

    
    

    通过上面例子,我们可以知道,当我们实现单例时,为了保证线程安全需要在内部加入锁

    
    

    我们知道,当我们实例化一个对象时,是先执行了类的__new__方法(我们没写时,默认调用object.__new__),实例化对象;然后再执行类的__init__方法,对这个对象进行初始化,所有我们可以基于这个,实现单例模式

    复制代码
    import threading
    class Singleton(object):
        _instance_lock = threading.Lock()
    
        def __init__(self):
            pass
    
    
        def __new__(cls, *args, **kwargs):
            if not hasattr(Singleton, "_instance"):
                with Singleton._instance_lock:
                    if not hasattr(Singleton, "_instance"):
                        Singleton._instance = object.__new__(cls)  
            return Singleton._instance
    
    obj1 = Singleton()
    obj2 = Singleton()
    print(obj1,obj2)
    
    def task(arg):
        obj = Singleton()
        print(obj)
    
    for i in range(10):
        t = threading.Thread(target=task,args=[i,])
        t.start()
    复制代码

    打印结果如下:

    复制代码
    <__main__.Singleton object at 0x038B33D0> <__main__.Singleton object at 0x038B33D0>
    <__main__.Singleton object at 0x038B33D0>
    <__main__.Singleton object at 0x038B33D0>
    <__main__.Singleton object at 0x038B33D0>
    <__main__.Singleton object at 0x038B33D0>
    <__main__.Singleton object at 0x038B33D0>
    <__main__.Singleton object at 0x038B33D0>
    <__main__.Singleton object at 0x038B33D0>
    <__main__.Singleton object at 0x038B33D0>
    <__main__.Singleton object at 0x038B33D0>
    <__main__.Singleton object at 0x038B33D0>
    复制代码

    采用这种方式的单例模式,以后实例化对象时,和平时实例化对象的方法一样 obj = Singleton()

    5.基于metaclass方式实现(元类)

    相关知识

    """
    1.类由type创建,创建类时,type的__init__方法自动执行,类() 执行type的 __call__方法(类的__new__方法,类的__init__方法)
    2.对象由类创建,创建对象时,类的__init__方法自动执行,对象()执行类的 __call__ 方法
    """

    例子:

    复制代码
    class Foo:
        def __init__(self):
            pass
    
        def __call__(self, *args, **kwargs):
            pass
    
    obj = Foo()
    # 执行type的 __call__ 方法,调用 Foo类(是type的对象)的 __new__方法,用于创建对象,然后调用 Foo类(是type的对象)的 __init__方法,用于对对象初始化。
    
    obj()    # 执行Foo的 __call__ 方法    
    复制代码

    元类的使用

    复制代码
    class SingletonType(type):
        def __init__(self,*args,**kwargs):
            super(SingletonType,self).__init__(*args,**kwargs)
    
        def __call__(cls, *args, **kwargs): # 这里的cls,即Foo类
            print('cls',cls)
            obj = cls.__new__(cls,*args, **kwargs)
            cls.__init__(obj,*args, **kwargs) # Foo.__init__(obj)
            return obj
    
    class Foo(metaclass=SingletonType): # 指定创建Foo的type为SingletonType
        def __init__(self,name):
            self.name = name
        def __new__(cls, *args, **kwargs):
            return object.__new__(cls)
    
    obj = Foo('xx')
    复制代码

    实现单例模式

    复制代码
    import threading
    
    class SingletonType(type):
        _instance_lock = threading.Lock()
        def __call__(cls, *args, **kwargs):
            if not hasattr(cls, "_instance"):
                with SingletonType._instance_lock:
                    if not hasattr(cls, "_instance"):
                        cls._instance = super(SingletonType,cls).__call__(*args, **kwargs)
            return cls._instance
    
    class Foo(metaclass=SingletonType):
        def __init__(self,name):
            self.name = name
    
    
    obj1 = Foo('name')
    obj2 = Foo('name')
    print(obj1,obj2)

     




    三、python2和python3的区别:

    print 函数

    print语句没有了,取而代之的是print()函数。

    Unicode

    
    

    Python 2 有 ASCII str() 类型,unicode() 是单独的,不是 byte 类型。

    在 Python 3,我们最终有了 Unicode (utf-8) 字符串,以及一个字节类:byte 和 bytearrays

    除法运算

    Python中的除法较其它语言显得非常高端,有套很复杂的规则。Python中的除法有两个运算符,/和//

    首先来说/除法:

    在python 2.x中/除法就跟我们熟悉的大多数语言,比如Java啊C啊差不多,整数相除的结果是一个整数,把小数部分完全忽略掉,浮点数除法会保留小数点的部分得到一个浮点数的结果。

    在python 3.x中/除法不再这么做了,对于整数之间的相除,结果也会是浮点数。

    Python 2.x:

    >>> 1 / 2
    0
    >>> 1.0 / 2.0
    0.5

    Python 3.x:

    >>> 1/2
    0.5

    而对于//除法,这种除法叫做floor除法,会对除法的结果自动进行一个floor操作,在python 2.x和python 3.x中是一致的。

    python 2.x:

    >>> -1 // 2
    -1

    python 3.x:

    >>> -1 // 2
    -1

    注意的是并不是舍弃小数部分,而是执行floor操作,如果要截取小数部分,那么需要使用math模块的trunc函数

    python 3.x:

    >>> import math
    >>> math.trunc(1 / 2)
    0
    >>> math.trunc(-1 / 2)
    0


    异常

    在 Python 3 中处理异常也轻微的改变了,在 Python 3 中我们现在使用 as 作为关键词。

    捕获异常的语法由 except exc, var 改为 except exc as var

    使用语法except (exc1, exc2) as var可以同时捕获多种类别的异常。 Python 2.6已经支持这两种语法。

    • 1. 在2.x时代,所有类型的对象都是可以被直接抛出的,在3.x时代,只有继承自BaseException的对象才可以被抛出。
    • 2. 2.x raise语句使用逗号将抛出对象类型和参数分开,3.x取消了这种奇葩的写法,直接调用构造函数抛出对象即可。

    在2.x时代,异常在代码中除了表示程序错误,还经常做一些普通控制结构应该做的事情,在3.x中可以看出,设计者让异常变的更加专一,只有在错误发生的情况才能去用异常捕获语句来处理。

    不等运算符

    Python 2.x中不等于有两种写法 != 和 <>

    Python 3.x中去掉了<>, 只有!=一种写法,还好,我从来没有使用<>的习惯

    打开文件

    原:

    file( ..... )
     
    open(.....)

    改为只能用

    open(.....)

    从键盘录入一个字符串

    原:

    raw_input( "提示信息" )

    改为:

    input( "提示信息" )

    在python2.x中raw_input()和input( ),两个函数都存在,其中区别为:

    • raw_input()---将所有输入作为字符串看待,返回字符串类型
    • input()-----只能接收"数字"的输入,在对待纯数字输入时具有自己的特性,它返回所输入的数字的类型(int, float )

    在python3.x中raw_input()和input( )进行了整合,去除了raw_input(),仅保留了input()函数,其接收任意任性输入,将所有输入默认为字符串处理,并返回字符串类型。

    map、filter 和 reduce

    这三个函数号称是函数式编程的代表。在 Python3.x 和 Python2.x 中也有了很大的差异。

    首先我们先简单的在 Python2.x 的交互下输入 map 和 filter,看到它们两者的类型是 built-in function(内置函数):

    >>> map
    <built-in function map>
    >>> filter
    <built-in function filter>
    >>>

    们输出的结果类型都是列表:

    >>> map(lambda x:x *2, [1,2,3])
    [2, 4, 6]
    >>> filter(lambda x:x %2 ==0,range(10))
    [0, 2, 4, 6, 8]
    >>>

    但是在Python 3.x中它们却不是这个样子了:

    >>> map
    <class 'map'>
    >>> map(print,[1,2,3])
    <map object at 0x10d8bd400>
    >>> filter
    <class 'filter'>
    >>> filter(lambda x:x % 2 == 0, range(10))
    <filter object at 0x10d8bd3c8>
    >>>

    首先它们从函数变成了类,其次,它们的返回结果也从当初的列表成了一个可迭代的对象, 我们尝试用 next 函数来进行手工迭代:

    >>> f =filter(lambda x:x %2 ==0, range(10))
    >>> next(f)
    0
    >>> next(f)
    2
    >>> next(f)
    4
    >>> next(f)
    6
    >>>

    对于比较高端的 reduce 函数,它在 Python 3.x 中已经不属于 built-in 了,被挪到 functools 模块当中。

     



  • 相关阅读:
    [Lydsy1706月赛]大根堆
    某考试 T1 Function
    [SHOI2016] 随机序列
    某考试 T1 至危警告
    某考试 T2 yja
    bzoj1880 [Sdoi2009]Elaxia的路线
    bzoj1804 [Ioi2007]Flood 洪水
    bzoj4546 codechef XRQRS
    bzoj4547 小奇的集合
    bzoj1443 [JSOI2009]游戏Game
  • 原文地址:https://www.cnblogs.com/1314520xh/p/9026987.html
Copyright © 2020-2023  润新知