代码语言:javascript复制
def tryok(any_var_str = '^Tryok', output_tips = -1, version = 'ver-1.21'):
# === 【★★★】=== 该方法属于-任意变量/对象/模块-询值-正逻辑-测试函数-在当前或外部文件均可调用---存在返回-真-否则返回-假
# === 【正逻辑】测试-对任何变量、对象、模块检查其是否【存在】是-则为真-否则为假,相应的名称串需要用单或双引号括起来
# === 若在变量名首位增加 ^ 符号,则表明是按【负逻辑】测试返回结果,即:不存在为真,存在为假,该功能等同于方法:tryerr()
# === any_var_str:欲测试的任意全局变量-对象-模块名,output_tips:是否输出加载过程的提示信息,默认=-1,不提示,否则输出提示
# === 对于由点号组成的 any_var_str 属于-对象.属性名参数形式:其中的对象必须是全局型,属性名串应符合合规范
# === 其中的 version :参数-无意义,因为需要复制使用,所以要知道谁是最新的-以此方式作标记
any_var_str = any_var_str.replace(' ', '')
ON_OFF_PRINT = '0 0' if output_tips >= 0 else '00'
back_logic = True if any_var_str[0] == '^' else False
any_var_str = any_var_str[1:] if back_logic else any_var_str
sure = False
try:
if '.' in any_var_str:
one, two = any_var_str.split('.')
isok = hasattr(globals()[one], two)
sure = True if isok or 'NoneType' not in repr(isok) else False
if ON_OFF_PRINT == '0 0': print(here(0), F"① 查询-对象【{any_var_str}】属性-{'【存在】' if sure==True else '【不存在】'}")
else:
try:
var_val = sys._getframe(1).f_locals[any_var_str]
the = '模块' if '<module' in str(var_val) else '变量'
sure = True
if ON_OFF_PRINT == '0 0': print(here(0), F'② 查询-{the}【{any_var_str}】=值={var_val}')
except:
if ON_OFF_PRINT == '0 0': print(here(0), F'③ 查询-变量【{any_var_str}】-【不存在】')
except:pass
if back_logic:
sure = False if sure else True
if ON_OFF_PRINT == '0 0' : print(here(0), F"{any_var_str}-【负逻辑】测试【结论】-{sure}")
else:
if ON_OFF_PRINT == '0 0' : print(here(0), F"{any_var_str}-【正逻辑】测试【结论】-{sure}")
return sure
def here(s=['', 0, 1 , -1, 2, 3, 5, 35, 53][0], sayit = 1) :
# === 功能:获取并返回-调用本方法之当前行的行号以及其所在当前文件名-含路径、所在函数体之函数名称串与函数名对象引用
# === 参数sayit:是否语音播报行号。默认播报=1,=0或者非1值则不语音播报
# === 使用说明:当 s 缺省为空串时-返回-调用本方法here()当前行的行号数值
# === 使用说明:当 s =int= 0 时-返回-调用本方法here(0)当前行的行号标记文本,形如:F"当前位于【{lineno}】行"
# === 使用说明:当 s =int= 1 时-返回-本方法here(1)所在[路径各段,,,当前文件名,路径\]之列表项,here(1)[-1]=路径path
# === 使用说明:当 s =int=-1 时-返回-【顶层】调用本方法here(5),here(3)之组合-即列表[函数对象引用, 函数名称串]
# === 使用说明:当 s =int= 2 时-返回-【最近】一层调用本方法here(2)之[堆栈层级数, 行代码串]
# === 使用说明:当 s =int= 3 时-返回-【最近】一层调用本方法here(3)之函数名称串
# === 使用说明:当 s =int= 5 时-返回-【最近】一层调用本方法here(5)之函数名称的对象引用
# === 使用说明:当 s =int= 35/53 时-返回-【最近】一层调用本方法here(5),here(3)之组合-即列表[函数对象引用, 堆栈层级数, 函数名称串]
# === 使用说明:当 s =str= 字符串 时-返回-本方法here('xxx')当前执行位置的装饰标记性显示格式
# =================================================================
Q = str(s)
ql = len(Q.strip())
lineno = sys._getframe(1).f_lineno
if ql == 0 : return lineno
is_int = 'int' in str(type(s))
s_int = (True if Q in '-102535' else False) if is_int else False
if s_int and s == 0: return F"当前位于【{lineno}】行"
# =================================================================
if s_int:
rowmsgs = frames()
rowmsg = rowmsgs[-1]
lineno = rowmsg.uprow
filename = rowmsg.upfile
# =========================path = os.path.split(xpath)[0] filename = os.path.split(xpath)[1]
if s == 1: return filename.split(chr(92)) [filename[: filename.rfind(chr(92), 1)] chr(92)]
if s==-1 : return [rowmsg.topcall, rowmsg.topname]
if s==2 : return [rowmsg.upidx,rowmsg.upcode]
if s==3 : return rowmsg.upname
if s==5 : return rowmsg.upcall
if s==35 or s==53 : return [rowmsg.upcall, rowmsg.upidx, rowmsg.upname]
elif is_int:return lineno
# =======================================================================
# === 以下是处理标记-本方法here('xxx')当前执行位置的装饰标记性显示格式
if sayit == 1 : Say(F"我在{lineno}行")
# =======================================================================
t = 'F"' "{' ' * SP}{'☀' * W32} ● TS -当前代码-运行至此:【 " str(lineno) " 】行 ● {'☀' * W32}{' ' * SP}" '"'
m , g = 38 , 8
n , k , TS = len(Q) , m 5 ,'本页面文件'
if n > 0:
TS = Q if n < 21 else Q[:21]
k = m len(TS)
px = 120 - 24 - k - g
px = 12 if px < 12 else px
pk = 4 if px < 12 else 8
W32 = str(px // 2)
SP = str(pk // 2)
t = t.replace('SP', SP).replace('W32', W32).replace('TS', TS)
return eval(t)
def frames(nList_mTuple = -2):
# === 功能:查询并获取当前各层级堆栈信息列表。实际返回-已扣除了-frames()-本级调用,即总层级数应减 1
# === 参数nList_mTuple:是一个行列代号组成的1~2位正整数数字码,n 取自列表中的序号码-nList,m 取自其中各层帧结构-元组中的序号码-mTuple
# === 由此可直接返回所需要的元素值(若值=-1即返回【对象引用】,<-1的负值无效),而非返回整个列表和对象引用。比如参数值=23,即返回:第 2 层堆栈帧中-调用函数所在行之代码串。
# === 【特别说明】参数nList_mTuple若为字符串-则是作为检索某个有特征关键字的帧序号耐用-此时函数返回对象引用。检索结果赋于self.upidx属性
# === 返回列表结构-列表-(nList的代号 n=):[0-当前调用堆栈总层级数, (1-层-最近的-调用堆栈信息), (2-层-上一层-调用堆栈信息), (3-层...),,, (-2 = n-顶层-调用堆栈信息), -1 = self-对象属性引用]
# === 各层信息结构-元组-(mTuple-代号 m=):(0-本层堆栈级数, 1-调用函数名称串, 2-调用函数所在行号, 3-调用函数所在行之代码串, -2=4-调用函数引用对象, -1=5=调用函数所在之文件名)
# === 返回【列表 对象引用】双结果:从列表-到-对象取用:self=返回列表项[-1]=frames()[-1]
# --- self.maxdepth:最大堆栈层级数-其中包含了本级-即 0 层=frames(),属于页面层级
# --- self.toplevel:这个是从1级调用开始的实际堆栈层级数-排除了:frames() 这一级-0层
# --- self.upidx # 上一层-外部文件中-最近一次调用之堆栈层级帧数
# --- self.upname # 上一层-外部文件中-最近一次调用函数之名称串
# --- self.uprow # 上一层-外部文件中-最近一次调用函数所在之行号
# --- self.upcode # 上一层-外部文件中-最近一次调用函数所在行之行代码串
# --- self.upcall # 上一层-外部文件中-最近一次调用函数之对象引用
# --- self.upeqvar # 上一层-外部文件中-最近一次调用函数所在行代码中等号左侧的赋值变量名
# --- self.LEFTVAR # 同上---只是为了使用时的一个特征标记属性
# --- self.upfile # 上一层-外部文件中-最近一次调用函数所在之全路径文件名
# --- self.topidx # 在外部文件中-顶层调用之堆栈层级帧数
# --- self.topname # 在外部文件中-顶层调用之函数的名称串
# --- self.toprow # 在外部文件中-顶层调用之函数所在之行号
# --- self.topcode # 在外部文件中-顶层调用之函数所在行之行代码串
# --- self.topcall # 在外部文件中-顶层调用之函数的对象引用
# --- self.topeqvar # 在外部文件中-顶层调用函数所在行代码中等号左侧的赋值变量名
# --- self.topfile # 在外部文件中-顶层调用之函数所在之全路径文件名
# ●∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
call_bydef_ref, get_1_locals, get_2_locals, get_1_frame, Self_Name = None, None, None, None, None
call_bydef_row, call_bydef_name, callby_code, callby_file = -1, '', '', ''
frames_depth, frames_detail = 0, []
InOutCall = InThisFileCall() # 检测-frames()函数-是在本文件中调用-True,还是在外部文件调用-False
# ●∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
nLIST_mTUPLE = nList_mTuple if what(nList_mTuple, 'int') else -1 # 返回对象引用
findkey = nList_mTuple if what(nList_mTuple, 'str') else None
idxFound = None
# ●∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
while True:
if frames_depth > 0 and call_bydef_name != '<module>':
frames_detail.append((frames_depth, call_bydef_name, call_bydef_row, callby_code, call_bydef_ref,callby_file))
get_f_code = sys._getframe(frames_depth).f_code
call_bydef_name = get_f_code.co_name
if frames_depth == 0: Self_Name = call_bydef_name "("
try:
get_1_frame = sys._getframe(frames_depth 1)
get_1_locals = get_1_frame.f_back.f_locals
get_2_locals = sys._getframe(frames_depth 2).f_back.f_locals
except:get_2_locals = get_1_locals
call_bydef_row = call_bydef_row if call_bydef_name == '<module>' else get_1_frame.f_lineno
callby_file = get_1_frame.f_code.co_filename
callby_code = RAM_Cache.getline(callby_file, call_bydef_row).strip()
pos = callby_code.rfind('#', 1)
callby_code = callby_code[:pos].strip() if pos > 0 else callby_code
if findkey != None and idxFound is None:
idxFound = frames_depth 1 if (findkey '(') in callby_code and Self_Name not in callby_code else idxFound
fx_at_locals = F"<function {call_bydef_name} at"
try:
if frames_depth == 0:
call_bydef_ref = globals().get(call_bydef_name)
elif fx_at_locals in repr(get_1_locals):
call_bydef_ref = get_1_locals[call_bydef_name]
elif call_bydef_name == '<module>' or fx_at_locals in repr(get_2_locals):
call_bydef_ref = get_2_locals[call_bydef_name]
except:pass
if call_bydef_name == '<module>':break
frames_depth = 1
# ●∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
self = globals().get(frames_detail[0][1]) # 当前函数体内获取本函数隐式对象的引用
frames_detail = [frames_depth] frames_detail [self]
self.toplevel = frames_depth
self.maxdepth = self.toplevel 1
# ●∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
upcall_depth = idxFound if idxFound != None else 2 if InOutCall and frames_depth >= 2 else frames_depth
self.upidx = frames_detail[upcall_depth][0]
self.upname = frames_detail[upcall_depth][1]
self.uprow = frames_detail[upcall_depth][2]
self.upcall = frames_detail[upcall_depth][-2]
self.upfile = frames_detail[upcall_depth][-1]
# ==================================================================
upco = frames_detail[upcall_depth][3]
self.upcode = upco
eqh, zkh = upco.find('='), upco.find('(')
self.upeqvar = None if eqh < 0 or eqh > zkh else upco.split('=')[0].strip()
self.LEFTVAR = self.upeqvar
# ●∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
self.topidx = frames_detail[-2][0]
self.topname = frames_detail[-2][1]
self.toprow = frames_detail[-2][2]
self.topcall = frames_detail[-2][-2]
self.topfile = frames_detail[-2][-1]
# ==================================================================
upco = frames_detail[-2][3]
self.topcode = upco
eqh, zkh = upco.find('='), upco.find('(')
self.topeqvar = None if eqh < 0 or eqh > zkh else upco.split('=')[0].strip()
RAM_Cache.clearcache()
# ●∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
try:
eleIdx = nLIST_mTUPLE
except:eleIdx = -1
if eleIdx == -1:
return self
elif eleIdx < -1:
return frames_detail # 返回列表-到对象引用取用:self=frames_detail[-1]
else:
eleIdx = int(eleIdx)
idxStr = str(eleIdx).strip()
idxStr = idxStr[0] if eleIdx < 10 else idxStr[:2] # 最多取用 2 位
# 即最大处理 10 级调用帧结构堆栈-太多也无意义
if eleIdx < 10 and eleIdx < len(frames_detail):return frames_detail[eleIdx]
n, m = int(idxStr[0]), int(idxStr[1])
m = 0 if m > len(frames_detail[1]) else m
return frames_detail[n][m]
def tryerr(any_var_str = 'TryError', output_tips = -1, version = 'ver-1.21'):
# === 【★★★】=== 该方法属于-任意变量/对象/模块-询值-负逻辑-测试函数-在当前或外部文件均可调用---存在返回-假-否则返回-真
# === 【负逻辑】测试-对任何变量、对象、模块检查其是否【存在】是-则为假-否则为真,相应的名称串需要用单或双引号括起来
# === 该功能等同于方法:tryok(any_var_str = '^Tryok') 即首位加 ^ 符号之逻辑
# === any_var_str:欲测试的任意全局变量-对象-模块名,output_tips:是否输出加载过程的提示信息,默认=-1,不提示,否则输出提示
# === 对于由点号组成的 any_var_str 属于-对象.属性名参数形式:其中的对象必须是全局型,属性名串应符合合规范
# === 其中的 version :参数-无意义,因为需要复制使用,所以要知道谁是最新的-以此方式作标记
any_var_str = any_var_str.replace(' ', '')
ON_OFF_PRINT = '0 0' if output_tips >= 0 else '00'
fail = True
try:
if '.' in any_var_str:
one,two = any_var_str.split('.')
isok = hasattr(globals()[one], two)
fail = False if isok or 'NoneType' not in repr(isok) else True
if ON_OFF_PRINT == '0 0': print(here(0), F"① 查询-对象【{any_var_str}】属性-{'【存在】' if fail==False else '【不存在】'}")
else:
try:
var_val = sys._getframe(1).f_locals[any_var_str]
the = '模块' if '<module' in str(var_val) else '变量'
fail = False
if ON_OFF_PRINT == '0 0': print(here(0), F'② 查询-{the}【{any_var_str}】=值={var_val}')
except:
if ON_OFF_PRINT == '0 0': print(here(0), F'③ 查询-变量【{any_var_str}】-【不存在】')
except:pass
if ON_OFF_PRINT == '0 0': print(here(0), F"{any_var_str}-【负逻辑】测试【结论】-{fail}")
return fail
def tryload(load_module_name = None, output_tips = -1, version = 'ver-1.19'):
# === 【★★★】=== 该方法属于-模块-动态加载方法-在当前或外部文件均可调用---多次调用只会首次加载-后续调用只是引用而已
# === 测试符合:import XXX 这一格式的模块加载表达式的模块-是否-未加载-是-则为真,模块名需要用单或双引号括起来
# === load_module_name:欲加载的模块名,output_tips:是否输出加载过程的提示信息,默认=-1,不提示,否则输出提示
# === 其中的 version :参数-无意义,只是为了标记其最新版本而已
# === 若相关模块未加载-则-加载它-并返回该模块对象,它有三种应用格式:
# [格式 1] XXX = tryload(),即缺省参数时,其等式左侧的 XXX 必须是合法的且已安装有效的模块名称字符串(以下有关 XXX 的定义相同)
# [格式 2] XXX = tryload('XXX'),即参数值与其等式左侧的 XXX 同名---同名加载,格式1为缺省加载,格式3为别名加载
# [格式 3] module_alias_name = tryload('XXX'),即参数值与其等式左侧的 XXX 不同,则module_alias_name即为 XXX 模块的别名
# === 本方法-方式 1-调用方式示例:win32 = tryload('win32gui'),方式2:win32gui = tryload()
calls = FRAMES('tryload')
call_name = calls.LEFTVAR # 获取直接调用tryload()方法之代码行赋值等号左侧的变量名即模块名称或别名
ON_OFF_PRINT = '0 0' if output_tips >= 0 else '00'
if load_module_name == None or len(load_module_name.strip()) == 0:
load_module_name = call_name
load_module_name, load_module = load_module_name.replace(' ', ''), None
if call_name == load_module_name:
alias, the = load_module_name, '同名'
else:
alias, the = call_name, '别名'
try:
load_module = globals()[alias] # load_module = eval(load_module_name)
if ON_OFF_PRINT == '0 0': print(here(0),F'[{the}]-该模块-已存在')
except:
try:
code = F"import {load_module_name} as {alias}"
exec(code, globals())
load_module = globals()[alias] # load_module = eval(load_module_name)
if ON_OFF_PRINT == '0 0': print(here(0), F'【模块】{load_module_name}--[{the}]--加载')
except:Say('该模块加载失败')
the = '【失败】' if load_module is None else '【成功】'
if ON_OFF_PRINT == '0 0': print(here(0), F"【模块】{load_module_name}-【加载】-{the}")
return load_module