python不用显示释放内存,reference count 引用计数,如果不用就减一,当为0的时候,释放内存,refcunt -1。
竞争冒险,进程有多个线程运行,减小不是antomc也即不是原子性,可能会有其他进程插入,无法保证每个object被正常释放。,
解决:加锁,确保程序只有一个线程运行。
a = 1
lock.aquire()
if a > 0:
a -= 1
GIL是全局锁。只有一个线程锁,避免死锁。
问题有什么,在多核cpu时代。用多进程避开GIL问题。2.自己写cexctention
描述器
class Name:
def __get__(self, obj, objtype):
return "Peter"
class A:
name = Name()
print(A.name)
这个会调用class A的get函数。
claas Name:
def __get__(self,obj, objtype):
return "Peter"
class A:
def __init__(self):
self.name = Name()
o = A()
print(0.name)
打印的是main的函数初始化的意思。
load_attr,当使用.name,调用description的时候调用load_attr,
装饰器。装饰器就是将函数作为一个对象传入另外一个函数当中进行运算。
在python中函数也是一个对象,所以函数也可以被当作参数传入,calc_number
def double(x):
return x ** 2
def triple(x):
return x ** 3
def calu_number(func,x):
return func(x)
calu_number(double,3)
calu_number(triple,3)
# 6 # 9
函数本身也可以作为返回值。
def calu(n):
def multiple(x):
return n * x
return multiple
double = calu(2)
triple =calu(3)
print(doulbe(2))
print(triple(3))
使用就是
def dec(f):
return 1
@dec
def f(x):
return x ** 2
print(f(x)) # 1
# 相当于
def dec(f):
def f(x):
return x ** 2
return 1
所以可以写一些插入相关功能的函数,比如时间装饰器。前面已经写过了。
带参数也是参数先调用一次返回参数,然后这个参数在调用函数。
有模板的,
import time
class Timer:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
star = time.time()
ret = self.func(*args, **kwargs)
print(time.time() - star)
return ret
@Timer
def add(a,b):
return a+ b
#d等价于
add = Timer(add)
class add_str(cls):
def __str__(self):
return str(self.__dict__) # 用字典的形式重载
cls.__str__ = __str__
return cls
@add_str
class MyObject:
def __init__(self,a,b):
self.a = a
self.b = b
MyObject = add_str(MyObject)
o = Myobject(1,2)
print(o)
{"a":1,"b":2}
生成器
本身生成器只能用next寻找下一个值,
python 什么会被认为True
a = False
if a is True:
return True
if a == True:
return True
if a:
return True
if bool(a):
return True
第二个,==不推荐,已经在python里面可以重载,__eql__,这样导致错误出现。
在源码当中,PyObject_IsTrue。内置数据,如果是数判断是不是0,如果是序列就判断是否是空。如果是自定义的,找是否有__bool__这个属性,如果有的话,调用
func = lookup_maybe_method(self, &PyId_bool__, &umbound);
if (func == NULL){
if (PyErr_Occurred()){
return -i;
}
已经是否定义lens,也即判断有没有bool属性或者长度属性,如果都没有,返回1
MRO 多继承
可以继承其他的方法和数据,printA。python的mro用的是C3算法。
local class walk,
单调性。任何class使用方法来自于直接父类。
Class里面的self的意思。
建立对象的时候才会出现。也即调用对象的时候才能知道是self.也即实例化类才能调用。
class A:
def f(self,data):
print(self.name)
print(data)
o = A()
print(A.f())
print(o.f())
如果给o赋值o.name = "FS" 调用用的是描述器。
起效果的是function里面的descripe函数。
MethodClass
class M(type):
def __new__(cls, name, bases, dict):
return type.__new__(cls, name, bases, dict)
class A(metaclass = M):
pass
A = M("A", (),{} )
o = A()
此处,o =A()会调用A的new 和init函数,当然,A= M(“A“,(),{})的时候,也会调用m的init和new,这个调用是隐式的。
class M(type):
def __new__(cls, name, bases, dict):
return type.__new__(cls, name, bases, dict)
def __init__(self, name, bases, dict):
return type.__init__(seflf, name, bases, dict)
def __new__(cls, name, bases, dict):
return type.__new__(cls, name, bases, dict)
__new__ 是实例化这个对象,__iniit__ 初始化这个对象。—__call__ 新建的类产生实例的时候调用的。
__slots__ 建立白名单,使得函数更具有健壮性。速度快更加节省内存,
@ super().超类继承关系
当在类中调用关于super()的信息的时候,函数中见的代码变成,在封装的时候,其他人已经做的很好了,我们只要增加一些功能的话,可以直接用super(),继承父类的方法,
class Animal:
def __init__(self, age):
self.age = age
class Person(Animal):
def __init__(self, age, name):
self.name = name
class Male(Person):
def __init__(self, name , age):
super(Person, self).__init__(age)
self.gender = "male"
m = Male(33,"perter")
print(m)
super(cls, self) 第一个决定从哪开始找,第二个决定函数对象和mro
class A:
def __init__(self):
print("A")
class B(A):
def __init__(self):
super(B,self).say()
class C(A):
def __init__(self):
print("C")
class M(B,C):
def __init__(self):
B.say(self)
m = M()
m.say() #C
#因为M 的mro是 BCA 在b上调用self,走的是m的mro,所以从b开始,然后到c,发现直接输出c
在B
staticmethod和classmethod
class A:
@staticmethod
def F(x):
print(x)
A.f(1) # 1
可以将功能绑定在类上,而不是类的对象上很有用,虽然同样可以在类的对象上调用这个方法。,
class A:
@classmethod
def F(cls,x):
print(cls,x)
A.f(1) # <class object >1
会把class当作第一个对象传进来。
atexit module 只有两个函数
在python退出的时候,运行一些代码。
import atexit
def f():
print(""exit")
atexit.register(f)
或者在register传入参数。
@atexit.register
def f():
print("exit")
atexit.unregister(f)
Malloc内存管理系统
在系统里面有一个block和一个pool
asyncio处理需要等待任务
namedtuple
为了创建数据的时候,以后还记得自己创建的数据是什么意思,这里有一个很好的数据结构是nametuple,意味着数据的描述很有用,使用数据结构的时候,对数据的分析在于是否能表达完全,。
比如设置坐标的时候,nametuple的作用就显而易见。
from collections import namedtuple
# 定义一个namedtuple类型plor,并包含name,sex和age属性。
User = namedtuple('Plor', ['x', 'y'])
#赋值
User = User(x = '22', y = '23')
#或者用一个列表
User= User._make(['22','23'])