data_month = "202403"
def aa():
print(data_month)
aa()
data_month = "202404"
aa()
202403 202404 |
|
|
|
|
|
|
|
|
None与True
a = None not a # True
for与break
aa=[4,5,6]
bb=[7,8]
i=0
for a in aa:
for b in bb:
i=i+1
break
print(i)
输出:
1
2
3
while + break
a =1
b =3
while True:
if a == b:
break
a = a + 1
def register_function(*, name, description, parameters, function, **kwargs):
pass
* 的作用
它分隔了位置参数和关键字参数。
在 * 之前的参数(这里是 self)可以按位置或关键字传递。
在 * 之后的所有参数(name, description, parameters, function, **kwargs)
必须通过关键字传递,不能通过位置传递。
为什么这样设计: 提高代码可读性:强制调用者明确指定参数名,避免因参数顺序错误导致的逻辑问题。 避免歧义:当函数有多个参数时,关键字参数能更清晰地表达参数的用途。 允许的调用方式(关键字参数)
register_function(
name="func_name",
description="Does something",
parameters={"key": "value"},
function=lambda x: x + 1
)
不允许的调用方式(位置参数)
# 会触发 TypeError: register_function() takes 1 positional argument but 5 were given
register_function("func_name", "Does something", {"key": "value"}, lambda x: x + 1)
补充说明
如果函数定义中没有 *,所有参数默认都可以通过位置或关键字传递。
**kwargs 表示接受任意额外的关键字参数,与 * 无直接关系,
但这里两者结合进一步强化了关键字参数的灵活性。
这种设计在标准库中很常见,
例如 dict.get(key, default=None) 中的 default 也是一个仅限关键字参数。
|
|
|
|
|
|
|
|
获取构造函数定义变量 获取类属性
静态方法: 否 否
类方法: 否 可
实例方法: 可 可
class Stat():
def __init__(self):
pass
@classmethod
def m1(cls):
"""通过cls访问类的属性
"""
pass
@staticmethod
def m2():
pass
---------------------------------------------------------------------- |
if hasattr(model, 'predict_proba') and callable(getattr(model, 'predict_proba')):
print("obj has a callable my_method")
else:
print("obj does not have a callable my_method")
这个示例不仅检查 my_method 是否存在,还确保它是可调用的。 |
|
|
|
|
|
|
文件路径
命令行路径,比如 /opt/app/python3/bin/python /opt/tpf/aiwks/code/aisty/kl/db/db.py 不管下面代码是写在db.py中,还是写在db.py相关import的文件中,它是值永远是python命令后面执行的那个文件 import sys print(sys.argv[0]) # /opt/tpf/aiwks/code/aisty/kl/db/db.py print(os.path.abspath(__file__)) # /opt/app/python3/lib/python3.9/site-packages/tools/db.py 这三行代码是写在一起的,但__file__打印的是当前代码文件的路径,而不是命令行参数路径
某个模块路径
import sklearn2pmml print(sklearn2pmml.__file__) # 包路径 print(xxx.__code__) # 包函数
一个月有多少天
import calendar days = calendar.monthrange(2022,11)[1] print(days) 30 第一个参数是 上一个月 最后一天 是星期几,星期日为0
python字符串转时间
import datetime ss = '2022-11-01 00:00:00' date_time = datetime.datetime.strptime(ss,"%Y-%m-%d %H:%M:%S") # 2022-11-01 00:00:00 class 'datetime.datetime' print(date_time,type(date_time))
python时间+一个时间段
import datetime
current_time = datetime.datetime.now()
# 加一小时,2023-02-07 17:24:52
print((current_time+datetime.timedelta(hours=1)).strftime("%Y-%m-%d %H:%M:%S"))
# 加一分钟,2023-02-07 16:25:52
print((current_time+datetime.timedelta(minutes=1)).strftime("%Y-%m-%d %H:%M:%S"))
# 加一天,2023-02-08 16:24:52
print((current_time+datetime.timedelta(days=1)).strftime("%Y-%m-%d %H:%M:%S"))
|
遍历与包含
char_to_id = {"我":1,"皆":2}
for key in char_to_id:
print(key)
我
皆
for key in char_to_id.keys():
print(char_to_id[key])
1
2
print("无" in char_to_id)
False
|
|
默认引用
dd = {"aa":"a"}
cc = dd
cc["aa"] = 3
print(dd) # {'aa': 3}
d2 = {"dd":dd}
dd["aa"] = 5
print(d2["dd"]["aa"]) # 5
dict_a = {"a":123}
def test_dict(dict_a):
dict_a["b"] = 3
test_dict(dict_a)
dict_a
{'a': 123, 'b': 3}
|
|
key可为整数
word2id之后,id2word会用到
```python
>>> a={}
>>> a[0]=1
>>> print(a[0])
1
|
|
setdefault
inputs = list()
char_to_id = {"我":1,"皆":2}
text = "无我皆我"
D = -1
inputs.append([
[
char_to_id.setdefault(char, D) for char in text if len(char.strip())>0
]
])
print(inputs) # [[[-1, 1, 2, 1]]]
print(char_to_id) # {'我': 1, '皆': 2, '无': -1}
|
|
get
get时可以指定默认值,但它只是取值,并不会改变原字典
a = char_to_id.get("a",-1)
print(a)
|
|
一次取出key,value
a = {'a':1,'b':2,'c':3}
for k,v in a.items():
print(k,v)
import torch a = torch.tensor(1) # tensor(1) a.item() # 1 |
|
合并·update
dict1 = {'A': 1, 'B': 2, 'C':3}
dict2 = {'B': 4, 'D': 5}
dict1.update(dict2) #{'A': 1, 'B': 4, 'C': 3, 'D': 5}
|
|
字典顺序
char_to_id = {"a":1,"b":2,"c":3,"d":4,"e":5}
count1 = 0
count2 = 0
count3 = 0
count4 = 0
count5 = 0
for i in range(1000000):
count6 = 0
for key in char_to_id:
count6 += 1
if count6 == 1:
count1 += char_to_id[key]
if count6 == 2:
count2 += char_to_id[key]
if count6 == 3:
count3 += char_to_id[key]
if count6 == 4:
count4 += char_to_id[key]
if count6 == 5:
count5 += char_to_id[key]
if count6 == 6:
count6 += char_to_id[key]
count1,count2,count3,count4,count5
(1000000, 2000000, 3000000, 4000000, 5000000)
循环100万次,第n个key永远会第n次输出,这说明字典的写入顺序即为输出顺序
|
a = {'a':1,'b':2,'c':3}
a.values()
dict_values([1, 2, 3]) 输出列表的顺序与dict定义的顺序一致 list(a.values()) [1, 2, 3] ---------------------------------------------------------------------- |
scaler_params = {}
if scaler_params:
print(1)
else:
print("空")
空 ----------------------------------------------------------------------------- |
|
|
|
|
|
包含 a=["aa","b"] "b" in a #True "c" in a #False |
|
append 追加一个元素 a=[1,2,3] a.append(4) a [1, 2, 3, 4] |
|
extend 合并两个列表,等效于+ a=[1,2,3] b=[4,5,6] a.extend(b) a [1, 2, 3, 4, 5, 6] a=[1,2,3] b=[4,5,6] a+b [1, 2, 3, 4, 5, 6] |
|
insert在指定索引位置插入一个数据 a=[1, 2, 3] a.insert(0,0) a [0, 1, 2, 3] |
|
[1]*5 [1, 1, 1, 1, 1] |
a=[1,1,1]
def geta(a):
a[1]=2
geta(a)
a
[1, 2, 1]
|
|
sorted a= sorted([2,1,3]) a [1, 2, 3] ll=[[109,'aa1'],[11,'aa2']] a= sorted(ll) a [[11, 'aa2'], [109, 'aa1']] 字符串 ll=[['109','aa1'],['11','aa2']] a= sorted(ll,key=lambda x:int(x[0])) a [['11', 'aa2'], ['109', 'aa1']] ll=[['109','aa1'],['11','aa2']] a= sorted(ll) a [['109', 'aa1'], ['11', 'aa2']] a=[2,1,3] a.sort() a [1, 2, 3] |
### **一、按索引删除**
#### 1. **`del` 语句**
- **功能**:直接通过索引或切片删除元素,**无返回值**。
- **示例**:
```python
my_list = [0, 1, 2, 3, 4]
del my_list[1] # 删除索引1的元素 → [0, 2, 3, 4]
del my_list[1:3] # 删除索引1到2的切片 → [0, 4]
```
#### 2. **`pop()` 方法**
- **功能**:删除指定索引的元素并返回该元素。**默认删除末尾元素**。
- **示例**:
```python
my_list = ['a', 'b', 'c']
removed = my_list.pop(1) # removed='b',列表变为 ['a', 'c']
last_item = my_list.pop() # last_item='c',列表变为 ['a']
```
### **二、按元素值删除**
#### **`remove()` 方法**
- **功能**:删除列表中**第一个匹配值的元素**,若值不存在则抛出 `ValueError`。
- **示例**:
```python
my_list = [1, 2, 3, 2, 1]
my_list.remove(2) # 删除第一个2 → [1, 3, 2, 1]
# 注意:若元素不存在需先检查,例如:
if 4 in my_list:
my_list.remove(4)
```
---
### **三、清空列表**
#### **`clear()` 方法**
- **功能**:移除列表所有元素,使其变为空列表。
- **示例**:
```python
my_list = [10, 20, 30]
my_list.clear() # 结果 → []
```
---
### **方法对比** | 方法 | 删除依据 | 返回值 | 异常处理 | 适用场景 | |------------|----------|----------|------------------------|------------------------| | `del` | 索引/切片 | 无 | 索引越界时抛出异常 | 需直接操作列表或删除切片 | | `pop()` | 索引 | 返回元素 | 索引越界时抛出异常 | 需获取被删除元素的值 | | `remove()` | 元素值 | 无 | 值不存在时抛出`ValueError` | 明确删除特定值的首个匹配项 | | `clear()` | 无 | 无 | 无 | 快速清空整个列表 | --- ### **操作建议** - **精确索引删除**:优先选择 `del` 或 `pop()`,需返回值时用 `pop()`。 - **按值删除**:使用 `remove()`,但需确保元素存在或提前捕获异常。 - **批量删除**:通过切片结合 `del` 实现高效操作。 |
|
|
|
|
set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}
intersect = set1 & set2
print(intersect) # 输出结果为 {3, 4}
set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}
intersect = set1.intersection(set2)
print(intersect) # 输出结果为 {3, 4}
多集合交集
set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}
set3 = {4, 5, 6, 7}
intersect = set1.intersection(set2, set3)
print(intersect) # 输出结果为 {4}
|
|
discard
my_set = {1, 2, "ok"}
my_set.discard("ok") # 移除元素ok
print(my_set) # 输出: {1, 2}
my_set.discard(6) # 6不在集合中,但没有任何错误或异常
print(my_set) # 输出: {1, 2}
remove:如果元素存在于集合中,则将其移除;如果元素不存在,则引发KeyError异常
my_set = {1, 2, 3, 4, 5}
my_set.remove(3) # 移除元素3
print(my_set) # 输出: {1, 2, 4, 5}
try:
my_set.remove(6) # 6不在集合中,会引发KeyError异常
except KeyError:
print("元素不在集合中")
print(my_set) # 输出: {1, 2, 4, 5}
|
数据类型
isinstance("aaa",str) #True
isinstance(0,int)
import numpy as np
isinstance(np.array([1,1]),np.ndarray) # True
isinstance(np.array([1,1])[0],np.ndarray)# False
numpy中单个元素不再是ndarray
import torch
isinstance(torch.tensor([1,1]),torch.Tensor) # True
isinstance(torch.tensor([1,1])[0],torch.Tensor) # True
torch中单个元素依然是tensor
xx: 公有变量 _x: 单前置下划线,保护变量,私有化属性或方法,不能用于’from module import *’ 以单下划线开头的表示的是protected类型的变量。 即保护类型只能允许其/类对象本身与子类对象进行访问。 是一个Python命名约定,表示这个名称是供内部使用的。 它通常不由Python解释器强制执行,仅仅作为一种对程序员的提示。 __xx: 双前置下划线,私有成员,表示的是私有类型的变量。 只能是允许这个类本身进行访问了,连子类也不可以访问; 避免与子类中的属性命名冲突,无法在外部直接访问(名字重整所以访问不到)。 Python解释器自动在这种双下划线的私有方法或者私有属性的前面加上了 _类名 , 所以使用原定义的变量名和方法名访问不了变量和方法, 在规范上,这种双下划线的私有方法和私有属性是不应该在外部访问的; Python保留了有双前导和双末尾下划线的名称,用于特殊用途。 这样的例子有,__init__对象构造函数,或__call__ --- 它使得一个对象可以被调用, 所以尽量不用这种表示方式,以免和python冲突; __xx__: 双前后下划线,特殊方法专用的标识,如 __init__()为代表的类构造函数等。 用户名字空间的魔法对象或属性。 例如:__init__ , __ 不要自己发明这样的名字 xx_: 单个末尾下划线(后缀)是一个约定,用来避免与Python关键字产生命名冲突; 像class或def这样的名称已经被一个关键字所占用,附加一个下划线来解决命名冲突; _:某个变量是临时的或无关紧要的
|
raise
raise Exception('手工抛出异常')
|
def divide_numbers(a, b):
try:
# 尝试执行以下代码块
result = a / b
print(f"结果是: {result}")
except ZeroDivisionError:
# 如果发生ZeroDivisionError(除以零),则执行以下代码块
print("错误: 不能除以零!")
except TypeError:
# 如果发生TypeError(例如,如果a或b不是数字),则执行以下代码块
print("错误: 输入类型不正确,请输入数字!")
except Exception as e:
# 捕获所有其他异常类型,并打印异常信息
print(f"发生了一个意外错误: {e}")
# 测试函数
divide_numbers(10, 2) # 应该输出: 结果是: 5.0
divide_numbers(10, 0) # 应该输出: 错误: 不能除以零!
divide_numbers(10, 'a') # 应该输出: 错误: 输入类型不正确,请输入数字!
divide_numbers('a', 2) # 应该触发Exception块,输出: 发生了一个意外错误: ...(具体错误信息取决于Python版本和解释器)
结果是: 5.0 错误: 不能除以零! 错误: 输入类型不正确,请输入数字! 错误: 输入类型不正确,请输入数字! |
|
|
|
|
|
|
import argparse
parser = argparse.ArgumentParser(description="Example script with argparse")
parser.add_argument("--batchno", type=int, required=True, help="批次号")
parser.add_argument("--param2", type=str, required=False, help="Second parameter (integer)")
args = parser.parse_args()
print(f"Parameter 1: {args.batchno}")
print(f"Parameter 2: {args.param2}")
result = str(args.batchno) + args.param2
print(f"Sum of parameters: {result}")
python de.py --batchno=123 |
import argparse
def main():
# 创建一个ArgumentParser对象
parser = argparse.ArgumentParser(description="Process some integers and names.")
# 添加参数
parser.add_argument("--name", type=str, required=False, help="A name")
parser.add_argument("--batchno", type=int, required=True, help="批次号")
# 解析参数
args = parser.parse_args()
# 使用参数
print(f"Name: {args.name}")
print(f"Model: {args.batchno}")
# 你可以在这里添加更多逻辑来处理这些参数
if __name__ == "__main__":
main()
|
|
|
|
|
|
|
|
方法一:使用abc模块
from abc import ABC, abstractmethod
class BaseClass(ABC): # 继承ABC表示这是一个抽象基类
@abstractmethod
def must_implement_method(self):
"""子类必须实现这个方法"""
pass
class ChildClass(BaseClass):
def must_implement_method(self):
print("子类实现了抽象方法")
# 使用
obj = ChildClass()
obj.must_implement_method() # 输出: 子类实现了抽象方法
# 如果子类没有实现抽象方法,实例化时会报错
class BadChild(BaseClass):
pass
# 下面这行会引发TypeError: Can't instantiate abstract class BadChild with abstract method must_implement_method
# bad = BadChild()
方法二:使用NotImplementedError(不推荐,但更简单)
class BaseClass:
def must_implement_method(self):
raise NotImplementedError("子类必须实现这个方法")
class ChildClass(BaseClass):
def must_implement_method(self):
print("子类实现了抽象方法")
# 使用
obj = ChildClass()
obj.must_implement_method() # 输出: 子类实现了抽象方法
bad = BaseClass()
# 下面这行调用会引发NotImplementedError
# bad.must_implement_method()
主要区别
abc模块方法:
更正式,是Python推荐的抽象基类实现方式
在实例化时就会检查是否实现了所有抽象方法
可以定义抽象属性等其他抽象成员
NotImplementedError方法:
更简单直接
只有在调用方法时才会报错
不够正式,缺乏早期检查
|
class Parent1:
def method1(self):
print("来自 Parent1 的方法")
class Parent2:
def method2(self):
print("来自 Parent2 的方法")
class Child(Parent1, Parent2): # 继承多个类
def method3(self):
print("Child 自己的方法")
----------------------------------------------------------------------------
|
|
|
|
|
|
|
在 Python 里“验证一段代码能否正常运行”通常有两层含义:
A. 语法是否正确(Syntax Check)
B. 运行时是否抛异常(Runtime Check)
下面给出 3 种常用、可落地的做法,按“轻量→完整”排序,你按场景挑一个即可。
import ast
code = '''
def f(a, b):
return a+b +
'''
try:
ast.parse(code) # 只解析,不执行
print("语法 OK")
except SyntaxError as e:
print("语法错误:", e)
语法错误: invalid syntax (unknown, line 3)
|
用 exec / eval 在隔离字典里跑一遍,适合“小段独立代码”或“单个表达式”。
source = '''
def add(a, b):
return a + b
result = add(1, 2)
'''
g = {"__builtins__": __builtins__} # 可控的全局命名空间
l = {}
try:
exec(source, g, l) # 真正执行
print("运行 OK,result =", l["result"])
except Exception as e:
print("运行异常:", repr(e))
运行 OK,result = 3
注意:
若代码里有 import、open 等副作用,仍会影响真实文件系统;
若担心安全问题,可把 "__builtins__" 设成 {} 或自定义白名单。
|
使用标准库 subprocess + 临时文件做“全隔离”测试 当代码片段较大、带第三方依赖、或你想 100 % 隔离时,用子进程最稳妥。
import subprocess, tempfile, os
source = '''
import pandas as pd
df = pd.DataFrame({'a':[1,2], 'b':[3,4]})
print(df.shape)
'''
with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
f.write(source)
f.flush()
fname = f.name
try:
proc = subprocess.run(
['python', fname],
capture_output=True,
text=True,
timeout=10 # 防止死循环
)
if proc.returncode == 0:
print("运行成功:\n", proc.stdout)
else:
print("运行失败:\n", proc.stderr)
finally:
os.remove(fname)
运行成功: (2, 2) |
|
|
|
|