前言: 很多同学估计和博主一样,照葫芦画瓢 写点python是没问题的,理论上只要懂一门语言 学其它语言的基本语法都是很容易的,难点在于针对什么场景 用什么框架, 如何针对并发做设计等。
虽说我们画瓢都能画,但是基础的入门语法 还是要熟练的,博主是java开发 ,所以本文有时会以java的语言来阐述。
环境变量相关 移步博主首页搜索文章:python环境
tips: 本文由csdn博主 孟秋与你 编写,如读者在其它地方阅读到本文,
请前往百度搜索 孟秋与你csdn,进入博主主页后搜索
python中没有大括号,用冒号, 且缩进来表示层级 4个空格为1级
java用// 表示行注释,python用#表示,
java /** **/表示段落注释 , python用 “”" “”" (全英文双引号)表示
java代码:
/**
*测试
**/
public void test(){
// do something
}
python代码:
"""
测试
"""
def test():
if 1 == 1 :
# xxx
else:
# xxx
# do something
python中的main方法:
if __name__ == '__main__':
关键字区别:
python: self --> java: this
python None --> java: null
python super().method() --> java super.method (python中不算关键字)
python是弱类型,不需要手动声明变量类型(了解js的同学应该比较清楚是什么意思)
python即支持面向过程 也支持面向对象, 所以在python项目中 或许能看到大量面向过程的代码,或许还能看到大量混合使用的代码(对严格遵循p3c规范的同学来说 看python会非常不习惯),通俗点解释 面向过程直接以方法执行,面向对象执行方法时 需要以对象为载体
具体看注释
# 类的专有方法:
# __init__ : 构造函数,在生成对象时调用
# __del__ : 析构函数,释放对象时使用
# __repr__ : 打印,转换
# __setitem__ : 按照索引赋值
# __getitem__: 按照索引获取值
# __len__: 获得长度
# __cmp__: 比较运算
# __call__: 函数调用
# __add__: 加运算
# __sub__: 减运算
# __mul__: 乘运算
# __truediv__: 除运算
# __mod__: 求余运算
# __pow__: 乘方
class Parent:
def method(self):
print("父类...")
# 继承
class Child(Parent):
# (构造方法)
def __init__(self):
print("子类初始化")
# 重写
def method(self):
print("子类...")
def superMethod(self):
# 调用父类
super().method()
# 用来模拟多态
class Grandson(Parent):
def method(self):
print("孙子类...")
# 多态体现
def func(obj):
obj.method()
if __name__ == '__main__':
# 创建对象
obj = Child()
obj.method()
obj.superMethod()
# 多态体现
obj1 = Grandson()
func(obj1)
与java的主要区别在于:
def __init__(self):
python中有:
全局变量
类变量
实例变量
局部变量
全局变量是定义在所有class之外的,除了定义位置不同,其它和java的全局变量一样
类变量是定义在class里面 ,该class的所有def(方法)外面的, 类似于java的静态变量
实例变量 比较特殊 可以理解为能以在一个class里面的所有def方法内部定义 且可以在整个实例中传输的全局变量
(即只在该实例中传输的全局变量 定义位置在def方法里面)
局部变量:方法里面定义的 和java的局部变量一样
# 类的专有方法:
# __init__ : 构造函数,在生成对象时调用
# __del__ : 析构函数,释放对象时使用
# __repr__ : 打印,转换
# __setitem__ : 按照索引赋值
# __getitem__: 按照索引获取值
# __len__: 获得长度
# __cmp__: 比较运算
# __call__: 函数调用
# __add__: 加运算
# __sub__: 减运算
# __mul__: 乘运算
# __truediv__: 除运算
# __mod__: 求余运算
# __pow__: 乘方
class Parent:
def method(self):
print("父类...")
# 全局变量(class外)
b = 333
# 继承
class Child(Parent):
# 类变量 (class内)
a = 0
# (构造方法)
def __init__(self):
# 局部变量
c = 666
print(f"子类初始化{Child.a}")
Child.a = 1
# 重写
def method(self):
# 实例变量
self.a = 2
print(b)
print(f"子类...:{Child.a}")
def superMethod(self):
# 调用父类
super().method()
print(f"实例变量:..{self.a}")
# 用来模拟多态
class Grandson(Parent):
def method(self):
print("孙子类...")
# 多态体现
def func(obj):
obj.method()
if __name__ == '__main__':
# 创建对象
obj = Child()
obj.method()
obj.superMethod()
# 多态体现
obj1 = Grandson()
func(obj1)
loop_outer .py文件
# 测试Loop.py导包
def get_test_data():
arr = [1, 3, 5]
loop.py文件
# 导包
from loop_outer import get_test_data
def get_data():
inner_arr = [1, 3, 5]
return inner_arr
if __name__ == '__main__':
# 有返回值
res = get_data()
print(res)
for item in res:
print(item)
# 无返回值 返回None (快捷键ctrl+Q查看返回值)
res1 = get_test_data()
if res1 is None:
print("nothing")
else:
print(res1)
# 遍历字符串
my_string = "Hello"
for each_char in my_string:
print(each_char)
# 遍历字典
my_dict = {'a': 1, 'b': 2, 'c': 3}
for key, value in my_dict.items():
# f或F表示 f-strings(格式化字符串字面值),允许在字符串中包含变量和表达式的值
# 类似的还有r r或R开头的字符串会将反斜杠 \ 视为普通字符,而不是转义字符 在处理正则表达式、文件路径等场景中很有用。例如: r"C:\Users\xx
print(f"Key: {key}, Value: {value}")
dict_value = my_dict["c"]
print(f"测试字典取值:{dict_value}")
my_list = [1, 2, 3, 4, 5]
# for i 遍历
for index, item in enumerate(my_list):
print(f"Index: {index}, Value: {item}")
my_range_list = [5, 6, 7, 8]
# for index range 左闭右开[0,2)
for index in range(0, 2):
print(my_range_list[index])
arr = [1, 3, 5]
# 弹出下标(该数字从arr中也没了)
var = arr.pop(2)
print(var)
print(arr)
核心步骤:
1.获取锁 counter_lock = threading.Lock()
2. 使用锁 with counter_lock:
重要提示:我们自己写代码时 不要取名为 thread.py , 当其它依赖库python内置的thread.py时,会导致冲突,
比如我们在pycharm debug模式时 就会报错 : ‘module ‘thread‘ has no attribute ‘start_new_thread‘‘ ,原因是优先识别了我们写的thread.py模块
import threading
# 共享的计数器
counter = 0
# 线程工作函数,对计数器进行累加
def increment_counter():
global counter
for _ in range(1000000):
counter += 1
# 创建两个线程并同时启动
thread1 = threading.Thread(target=increment_counter)
thread2 = threading.Thread(target=increment_counter)
thread1.start()
thread2.start()
# 等待两个线程执行完成
thread1.join()
thread2.join()
# 打印最终的计数器值
print("Final counter value:", counter)
# -------------------------加锁---------------------
# 共享的计数器
safe_counter = 0
# 创建锁
counter_lock = threading.Lock()
# 线程工作函数,对计数器进行累加
def increment_counter():
global safe_counter
for _ in range(1000000):
with counter_lock:
safe_counter += 1
# 创建两个线程并同时启动
thread3 = threading.Thread(target=increment_counter)
thread4 = threading.Thread(target=increment_counter)
thread3.start()
thread4.start()
# 等待两个线程执行完成
thread3.join()
thread4.join()
# 打印最终的计数器值
print("Final counter value (with lock):", safe_counter)
重要提示: 使用了multiprocessing模块,其它方法需要在main方法中执行,因为multiprocessing会创建子进程,子进程会将当前模块代码重新加载一遍并执行,也就会导致main方法外的代码重复执行!例如我们下面的例子, thread_safe_queue 以及 print(thread_safe_queue.get())定义在main方法之外 就会重复打印。
multiprocessing本身也更是需要在main方法中,在windows环境下 multiprocessing会通过spawn方式创建子进程(unix下是os.fork()方式), 子进程复制一遍代码 复制的代码仍然是创建子进程 就会无限循环
导致报错:The “freeze_support()” line can be omitted if the program …
from queue import Queue
import multiprocessing
if __name__ == '__main__':
# 也可以写成 manager = multiprocessing.Manager()
with multiprocessing.Manager() as manager:
# 创建线程安全的列表
thread_safe_list = manager.list()
# 增加元素
thread_safe_list.append(66)
thread_safe_list.append(77)
# 移除元素
if 66 in thread_safe_list:
thread_safe_list.remove(66)
# 遍历元素
for item in thread_safe_list:
print(item)
# 线程安全的队列
thread_safe_queue = Queue()
thread_safe_queue.put(1)
thread_safe_queue.put(5)
# 没有提供直接的for循环遍历方式 可以通过 while not empty()的方式 不断get()
while not thread_safe_queue.empty():
print(thread_safe_queue.get())
如果是java开发,那对web框架的概念再熟悉不过了, 相应的 python中也有不少web框架
(对于框架 本文只做简述,毕竟对于程序员来说 最最重要的首先是要知道有这个东西,这是个从0到1的过程,知道有这么一个东西之后,我们可以轻而易举查到各种相关资料)
文章持续更新中…