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'])