首页 > 技术文章 > python语法

sailorlee11 2020-11-02 20:52 原文

python学习笔记

对象有三个特征:身份、类型和值

eg:a=1 就是a这个变量指向用int封装的这个1 的对象

type(a) ,打印出是int类型

type->class->obj

class是由type生成的一个对象,然后进行实列化

object是最顶层的基类

type也是一个类,继承object,同时他是自己实例化自己,所谓的实列化就是一个变量指针指向地址的内存块。

类型

None 作为全局的唯一

a=None,b=None,说明 a和b同时指向唯一的内存块 ,因此id(a)=id(b)

数值

int,float,complex(复数) ,bool

迭代类型

序列类型

映射

集合

上下文切换(with)

魔法函数

class Company(object):
    def __init__(self,employee_list):
        self.employee = employee_list
    def __getitem__(self,item):
        return self.employee[item]
    
company = Company(["tom","bob","jane"])

for em in company:
    print(em)

但是带有双下划线的函数则是魔法函数

类变量和实列变量

class A:
    aa = 1 
    def __init__(self,x,y):
        self.x = x
        self.y = y
a = A(4,5)
A.aa = 11
a.aa = 100
print(a.x,a.y,a.aa,A.aa)

打印出来分别是 4 ,5 ,100,11

当你调用 A.x的时候是打印出错,因为不可以往下调用实列化的数据。比如说来一个 b = A(3,4),实列化之后就不归类管,反之则是实列化后的数据可以调用类变量。

总结就是,查找变量是由下而上的去查找

类实列属性的查找循序

class D:
    pass
class C(D):
    pass
class B(D):
    pass
class A(B,C):
    pass
print(A.__mro__)

(<class 'main.A'>, <class 'main.B'>, <class 'main.C'>, <class 'main.D'>, <class 'object'>)

类方法、静态方法和实列方法

class Date:
    #构造函数
    day = 2
    def __init__(self, year, month, day):
        self.year = year
        self.month = month
        self.day = day

    def tomorrow(self):
        self.day += 1

    @staticmethod
    def parse_from_string(date_str):
        year, month, day = tuple(date_str.split("-"))
        return Date(int(year), int(month), int(day))

    @staticmethod
    def valid_str(date_str):
        year, month, day = tuple(date_str.split("-"))
        if int(year)>0 and (int(month) >0 and int(month)<=12) and (int(day) >0 and int(day)<=31):
            return True
        else:
            return False

    @classmethod
    def from_string(cls, date_str):
        year, month, day = tuple(date_str.split("-"))
        return cls(int(year), int(month), int(day))

    def __str__(self):
        return "{year}/{month}/{day}".format(year=self.year, month=self.month, day=self.day)

if __name__ == "__main__":
    new_day = Date(2018, 12, 31)
    new_day.tomorrow()
    print(Date.tomorrow())

    #2018-12-31
    date_str = "2018-12-31"
    year, month, day = tuple(date_str.split("-"))
    new_day = Date(int(year), int(month), int(day))
    print (new_day)

    #用staticmethod完成初始化
    new_day = Date.parse_from_string(date_str)
    print (new_day)

    #用classmethod完成初始化
    new_day = Date.from_string(date_str)
    print(new_day)

    print(Date.valid_str("2018-12-32"))

首先要确定一点,就是self是指代已经实列化的主题类。因此self.day是实列化后的day再加1,

如果是类本身的话,就是

@staticmethod

def tomorrow():
Date.day += 1

类方法则是 需要传入cls ,里面的cls就是指代类的本身 def from_string(cls, date_str)

tuple这个是用于拆分数据包的函数

数据封装和私有属性


super函数

class A:
    def __init__(self):
        print("A")

class B(A):
    def __init__(self):
        print("B")
        # 里面是获取父类,然后调用父类的init函数
        super().__init__()
class C(A):
    def __init__(self):
        print("C")
        super().__init__()

class D(B,C):
    def __init__(self):
        print("C")
        super().__init__()

from threading import Thread
class MyThread(Thread):
    def __init__(self,name,user):
        self.user = user
        super().__init__(name=name)#将构造函数交给父类进行实例化

if __name__ == "__main__":
    b= D()

mixin继承

特点:1 mixin类功能单一 2 不和基类关联,可以和任何一个基类组合,基类可以不和mixin关联就可以初始化成功

3 在mixin中不要使用super方法

with上下文管理器/协议

def exe_try():
    try:
        f_read = open("sailor.text")
        print("code started")
        # 抛出异常
        raise KeyError
        return 1
    except KeyError as e:
        print("key ")
        return 2
    else:
        print("other error")
        return 3
    finally:
        print("finally")
        # f_read.close()
        return 4

if __name__ =="__main__":
    result = exe_try()
    print(result)

此时返回的是4 不是2, 是因为return 2的时候,把2压入堆栈,在finally处得到return 4 再将4压入堆栈中,之后4先从堆栈中弹出。

class Sample:
    def __enter__(self):
        print("enter")
        return self
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("exit")
    def do_something(self):
        print("doing something")

with Sample() as sample:
    sample.do_something()

初始化的时候默认调用 enter方法,在enter上获取资源

调用with语句时候,默认调用exit方法,在exit上释放资源

最后打印出 enter doingsomething exit

import contextlib

@contextlib.contextmanager
def file_open(file_name):
    print("file open")
    yield {}
    print("file end")

with file_open("sailor.txt") as f_opened:
    print("file processing")

contextlib是将一个函数变成上下文管理器,其修饰的必须是一个生产器(yield)

执行部分先是 file open 接着是执行修饰器上的yield: file processing ,最后是 file end

推荐阅读