【Python】Python高级编程

Python高级编程

python中一切皆对象

—python中一切皆对象

内容

# 变量,函数,类,文件都是对象
[对象的三个特征]
1.身份
2.类型
3.[对象的性质]
1.赋值给一个变量
2.可添加到内置类型中
3.可作为参数传递
4.可作为函数的返回值

对象的三个特征

'''
以变量作为例子
'''

a = 1
print(id(a))   # 身份
print(type(a)) # 类型
print(a)       # 值
[输出]:
>>140706136249376
>><class 'int'>
>>1

对象的性质

'''
以类作为例子
'''

class Myclass:
    def say(self):
        print('hello')

# 1.类实例赋值给变量
myclass=Myclass()
a = list()
b = set()
c = dict()
d = set()

# 2.类实例放入内置数据类型
a.append(myclass)           # 将类实例放入列表
b = (myclass,)              # 将列实例放入元组
c.update({'class':myclass}) # 将类实例放入字典
d.add(myclass)              # 将类实例放入集合

# 3.调用类实例中的方法
a[0].say()                  # 调用Myclass类中say()方法
b[0].say()                  # 调用Myclass类中say()方法
c['class'].say()            # 调用Myclass类中say()方法
d.pop().say()               # 调用Myclass类中say()方法

# 4.类实例作为参数传递和作为函数返回值
def myfunc(class_instance):
    return class_instance   # 将类实例作为函数返回值
myfunc(myclass).say()       # 调用Myclass类中say()方法
[输出]:
>>hello
>>hello
>>hello
>>hello
>>hello

—type,object和class的关系

图解
在这里插入图片描述
说明

type 实例化生成所有类包括自身
object 被所有类和对象继承,但自身继承为空
type ->type
type ->int
type ->float
type ->complex
type ->bool
type ->dict
type ->set
type ->str
type ->list
type ->tuple
type ->bytes,bytearray
以上这些内置类型都可以看作是type实例化得到的对象
这些生成的对象又可以作为类实例化出对象,最后值不能再实例化

—python中的常见内置类型

None(全局只生成一个)
数值(int,float,complex,bool)
序列类型(str,list,tuple,range,bytes,bytearray,memoryview)
散列类型(dict,set)
迭代类型
上下文管理
其他

魔法方法

—字符串相关

方法名

__str__ __repr__

实例

class Myclass:
    def __init__(self,user_print,developer_print):
        self.user_print = user_print
        self.developer_print = developer_print
        
    def __str__(self):
        return self.user_print
    def __repr__(self):
        return self.developer_print

myclass = Myclass("面向用户的打印模式","面向开发的打印模式")
print(str(myclass))
print(repr(myclass))
[输出]:
>>面向用户的打印模式
>>面向开发的打印模式

多线程

创建线程

1.使用Thread方法创建线程

import threading # 引入threading多线程模块

def task(c1):
    print("传入的参数:",c1)
    print(threading.current_thread()) # 获取当前的线程名和线程ID


t = threading.Thread(target=task,args=(100,),name='子线程')
# target 参数传入函数名 
# args   参数传入函数需要的参数
# name   参数传入自定义的线程名

t.start() # 启动线程
t.join()  # 线程阻塞
print("主线程")

[输出]:
>>传入的参数: 100
>><Thread(子线程, started 13508)>
>>主线程

2.类的方式创建线程

import threading

class Mythread(threading.Thread):
    def __init__(self,name,c1):
        super().__init__() # 重写Thread类中的init方法
        self.name = name   # name参数传入自定义的线程名
        self.c1 = c1       # c1为传入的自定义参数

    def run(self):
        print("传入的参数:",self.c1)
        print(threading.current_thread()) # 获取当前的线程名和线程ID

t = Mythread(name='子线程',c1=100) # 传入线程名和自定义参数
t.start() # 启动线程
t.join()  # 线程阻塞
print("主线程")

[输出]:
>>传入的参数: 100
>><Mythread(子线程, started 10736)>
>>主线程

多线程常用方法和属性

Thread 类
	实例化线程
		对象=threading.Thread(name=自定义线程名,target=函数名,args=(参数,))
	设置线程名
		对象.setName(‘线程名’)
	获取线程名
		对象.getName()
	线程守护(主线程结束它的子线程就结束)
		对象.setDaemon(True)
	线程阻塞(主线程等子线程结束后才接着往下走)
		对象.join()
	判断线程是否存活
		对象.is_alive()
	通过对象获取线程ID
		对象.ident
	开启线程
		对象.start()
	获取所有线程详细信息列表
		threading.enumerate()
	在线程执行过程中获取所在线程名
		threading.current_thread().name
	在线程执行过程中中获取所在线程ID
		threading.current_thread().ident
	在函数执行过程中获取线程存活数量
		threading.active_count()

1.守护线程

import threading
import time
def task():
    time.sleep(5)
    print("子线程")

t = threading.Thread(target=task) # 传入要执行的函数名
t.setDaemon(True) # True :将线程设为守护线程 False :不将线程设为守护线程
t.start() # 启动线程
print("主线程")

[t.setDaemon(True)时输出]:
主线程

[t.setDaemon(False)时输出]:
主线程
子线程
  • 将线程设置为守护线程模式,主线程结束子线程也会立即结束
  • 若线程不是守护线程模式主线程结束后,还要所有子线程结束之后,整个程序才会结束

2.线程阻塞

import threading
import time
def task():
    time.sleep(5)
    print("子线程")

t = threading.Thread(target=task) # 传入要执行的函数名
t.start() # 启动线程
t.join()  # 线程阻塞
print("主线程")

[有t.join()语句时输出]:
子线程
主线程
[没有t.join()语句时输出]:
主线程
子线程
  • 将线程设置为线程阻塞模式,主线程要等子线程结束后才会结束,即子线程一定在主线程之前结束
  • 若线程不是线程阻塞模式主线程结束后,还要等所有子线程结束之后,整个程序才会结束

线程同步

1.全局解释器锁GIL

import threading
sum = 0
def income():
    global sum
    for i in range(1000000):
        sum += 1
        
def consume():
    global sum
    for i in range(1000000):
        sum -= 1
# 定义线程
t_income = threading.Thread(target=income)
t_consume = threading.Thread(target=consume)
# 启动线程
t_income.start()
t_consume.start()
# 线程阻塞
t_income.join()
t_consume.join()
# 打印变量计算结果
print("sum:",sum)

[输出]:
sum: 566204
  • GIL锁即python自带的全局解释锁,每次只能一个线程获得cpu的使用权,为了线程安全,也就是为了解决多线程之间的数据完整性和状态同步而加的锁,因为我们知道线程之间的数据共享的

  • 由于python的全局GIL锁机制,只要一个线程执行的字节码执行时间到指定值,则会自动释放GIL锁,此时多个线程可能同时对同一个变量同时操作,从而导致数据结果错误

  • 运行结果本应该输出sum: 0实际输出sum: 566204,是因为多个线程同时对同一个变量进行修改时,一个线程得到的计算值后,可能被另一个线程的计算的值给赋值

2.互斥锁 Lock

import threading

lock = threading.Lock()
sum = 0
def income():
    lock.acquire() # 加锁
    global sum
    for i in range(1000000):
        sum += 1
    lock.release() # 释放锁
    
def consume():
    lock.acquire() # 加锁
    global sum
    for i in range(1000000):
        sum -= 1
    lock.release() # 释放锁
# 定义线程
t_income = threading.Thread(target=income)
t_consume = threading.Thread(target=consume)
# 启动线程
t_income.start()
t_consume.start()
# 线程阻塞
t_income.join()
t_consume.join()
# 打印变量计算结果
print("sum:",sum)

[输出]:
sum: 0
  • 使用lock.acquire()lock.release()手动加锁保护变量后,使每次只有一个线程获得cpu的使用权,即在同一时间,只有一个线程对变量进行修改,所以数据并没有发生错误

3.递归锁 RLock


4.状态锁 Condition


线程通信

线程池

总结

CPU --> 进程 --> 线程 --> 无协程 --> 同步 --> 阻塞 --> IO --> 网络IO/文件IO                                                                                                					  
            --> 线程 --> 协程   --> 异步 --> 非阻塞 --> IO  --> 网络IO/文件IO                                                                                                                           

同一时间,同一个CPU中的多线程运行 --> 并发
同一时间,多个CPU中的多线程运行   --> 并行
'''常用数据类型特殊情况下的值'''
string1 = ''  # 0
string2 = ' ' # 1
list1 = []    # 0
list2 = [[]]  # 1
tuple1 = ()   # 0
tuple2 = (()) # 0
set1 = set()  # 0
dict1 = {}    # 0
null = None   # 0

if string1:
    print('string1')

if string2:
    print('string2')

if list1:
    print('list1')

if list2:
    print('list2')

if tuple1:
    print('tuple1')

if tuple2:
    print('tuple2')

if set1:
    print('set1')

if dict1:
    print('dict1')

if null:
    print('None')
[输出]:
string2
list2
发布了82 篇原创文章 · 获赞 468 · 访问量 24万+

猜你喜欢

转载自blog.csdn.net/qq_44647926/article/details/103223251