变量


data_month = "202403"
def aa():
    print(data_month)
aa()
data_month = "202404"
aa()

202403
202404











python循环控制

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

python方法

 
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 也是一个仅限关键字参数。

    

 

    

 


 

  

 


python类方法


         获取构造函数定义变量    获取类属性
静态方法:         否              否
类方法:           否              可
实例方法:        可               可


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 是否存在,还确保它是可调用的。







python路径

文件路径

命令行路径,比如
/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__)           # 包函数

python日期

一个月有多少天

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"))
python dict

遍历与包含

    
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("空")

 
----------------------------------------------------------------------------- 

 


 


python list

包含

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` 实现高效操作。












python set

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}

python 数据类型

数据类型

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

python 变量加下划线

xx: 公有变量

_x:
单前置下划线,保护变量,私有化属性或方法,不能用于’from module import *’
以单下划线开头的表示的是protected类型的变量。
即保护类型只能允许其/类对象本身与子类对象进行访问。
是一个Python命名约定,表示这个名称是供内部使用的。
它通常不由Python解释器强制执行,仅仅作为一种对程序员的提示。

__xx:
双前置下划线,私有成员,表示的是私有类型的变量。
只能是允许这个类本身进行访问了,连子类也不可以访问;
避免与子类中的属性命名冲突,无法在外部直接访问(名字重整所以访问不到)。
Python解释器自动在这种双下划线的私有方法或者私有属性的前面加上了 _类名 ,
所以使用原定义的变量名和方法名访问不了变量和方法,
在规范上,这种双下划线的私有方法和私有属性是不应该在外部访问的;
Python保留了有双前导和双末尾下划线的名称,用于特殊用途。
这样的例子有,__init__对象构造函数,或__call__ --- 它使得一个对象可以被调用,
所以尽量不用这种表示方式,以免和python冲突;

__xx__:
双前后下划线,特殊方法专用的标识,如 __init__()为代表的类构造函数等。
用户名字空间的魔法对象或属性。
例如:__init__ , __ 不要自己发明这样的名字

xx_:
单个末尾下划线(后缀)是一个约定,用来避免与Python关键字产生命名冲突;
像class或def这样的名称已经被一个关键字所占用,附加一个下划线来解决命名冲突;

_:某个变量是临时的或无关紧要的

python 异常处理

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
错误: 不能除以零!
错误: 输入类型不正确,请输入数字!
错误: 输入类型不正确,请输入数字!









python 脚本参数

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()









python 类

方法一:使用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中执行代码

 
在 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)

 


 

  

 


参考文章