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

时间:2021-09-06 16:19:09

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一年多了,今天碰到学习交流群里的一些问题:这里将它记录下来

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

 

 

 

 

 

 

 

 

 

当函数的参数不确定时,可以使用*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.使用装饰器

 
python学习总结---学习交流群里的问题总结
 
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.使用类

 
 
python学习总结---学习交流群里的问题总结
 
 
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

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

 
 

 

 
 
python学习总结---学习交流群里的问题总结
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()
python学习总结---学习交流群里的问题总结
 
 

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

 
 
python学习总结---学习交流群里的问题总结
<__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>
python学习总结---学习交流群里的问题总结
 
 

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

 
 

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

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

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

 
 
python学习总结---学习交流群里的问题总结
<__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>
python学习总结---学习交流群里的问题总结
 
 

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

 
 

 

 
 

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

 
 
python学习总结---学习交流群里的问题总结
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)
python学习总结---学习交流群里的问题总结
 
 

 

 
 

打印结果如下:

 
 
python学习总结---学习交流群里的问题总结
<__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>
python学习总结---学习交流群里的问题总结
 
 

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

 
 
python学习总结---学习交流群里的问题总结
    @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
python学习总结---学习交流群里的问题总结
 
 

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

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__方法,对这个对象进行初始化,所有我们可以基于这个,实现单例模式

 

 

python学习总结---学习交流群里的问题总结
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()
python学习总结---学习交流群里的问题总结

 

打印结果如下:

 

python学习总结---学习交流群里的问题总结
<__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>
python学习总结---学习交流群里的问题总结

 

 

 

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

 

 

 

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

相关知识

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

 

例子:

 

python学习总结---学习交流群里的问题总结
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__ 方法 
python学习总结---学习交流群里的问题总结

 

 

 

元类的使用

 

python学习总结---学习交流群里的问题总结
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')
python学习总结---学习交流群里的问题总结

 

 

 

 

实现单例模式

 

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

 

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 模块当中。