12 KiB
550W编辑代码时的帮助
______ BBBBQBBBBB________BBBBBBBBBB______ iEBBBBBK____________BBB__________ BBB
______.BB______________ dBP____________ rBQd:__ MB. :BPi____ :BBBR________ :QB:
______BB.______________ BQ____________ gBS______.QQ__LBQBJ__ BBBBB.________QBB
____ iQB r5DEq7.______ BBJ JdRDIi____ BB:________SQv__ .XBB. iB gBB______ rBB
____ BBBBBBBBBBBBR.__ rQBBBBBQBBBBBi__Zr__________BB____ :BB____.QB:______BBD
____.BBS______ .gBBY__5BBr______ 7BBM____________ iBP____ 7BZ____QBB____ YBB
________________ .BBi______________qBQ____________ gB:____ BB____ BBr____BB2
__________________:BB______________ QB7____________.BB____ BB.____PBB__ SBB
__________________ BB________________BB____________ 1Bj__ .QB______BBv__BQL
__________________ BB.______________ gBg____________ BB__ PB7______1BB IBB
__JR.______________JBB________________BQd____________:BP sBb________BBBBBi
__qBB:__________d7__QBB__________ QS__ BBB:__________ PBBB2________ rBQBQ
__ :BBBr____ .qBBR__ JBBBi____ :QBBd____rQBBP:____ ..__Qg.__________ BBB.
____ rBBBBBBBBQD.______uBBBBBBQBBX________.MBBBBBBBBQ________________.ri
前言
550W是一群流浪地球的粉丝几个大拿制作的一款仿550W UI的Python软件,其窗口使用Tkinter制作,为了方便维护,所有逻辑储存在Tools.py,所有UI储存在GUI.py
由于某个美涂士(MayDos)说该项目不长久,成功逼宫上位让550W的开发人员连夜升级,从零开始从新编辑,使得550W的编写难度更上(好几)一层楼,由于难度过高(加入明确需求的变量空间、信息类、空间类和模块类这几概念),为了防止开发人员和合作人员无法正常编辑(放弃项目),故有此帮助,以各位的水平,一定会来看的(确信)
第一部分 文件目录和作用
根目录
| 文件 | 作用 | 文件类型 |
|---|---|---|
| Main.py | 入口文件 | 文件 |
| Tools.py | 逻辑事件储存文件 | 文件 |
| test.py | 测试文件(测试某项功能) | 文件 |
| Module | Mod文件 | 文件夹 |
Module目录文件和Config.ini
标准Module目录结构*
| 第一层目录 | 第二层目录 | 第三层目录 | 第四层目录 |
|---|---|---|---|
| Module/ | Test/ | Config.ini | |
| Main.py | |||
| Lib/ | 1.py | ||
| Lib/ | 2.py |
这是一个标准Module的目录结构,目录结构的样式关键在于Config.ini,但Config.ini是很短的:
[CONFIG]
ENTRY=Main.py
DECODE=Python
LIBRARY=Lib
[CONFIG]是CONFIG标识,不过多解释
ENTRY是入口文件地址,填相对链接
DECODE是解码方式,Python为直接读取,Mod为使用BoxTools.Mod解码(客户端等数据需加密时使用)
LIBRARY是子模块的目录
可以填其他值,入口模块和子模块可以调用
第二部分模块启动讲解
Mod的启动需要依赖Tools.py来运行
Tools.py有几个class结构体
class Mod_Path():
def __init__(self):
class Mod:
def __init__(self,GlobalVariables,name):
def RunMain(self):
def RunSub(self,GlobalVariables,name):
class InFo:
def __init__(self):
self.path=str()
self.path_config=str()
self.Global=str()
self.config=str()
self.Entry=str()
self.Decode=str()
self.Library=str()
self.code=str()
self.file=str()
def RunSub(self,GlobalVariables,name):pass
Mod_InFo=InFo()
Mod_Path会创建一个可以让模块正常运行的变量空间,你需要理解变量空间这个东西,为了方便理解,我用代码来让你理解
a=1
b=2
def n(c):pass
class a():
def __init__(self):pass
这个文件的变量空间为
{
'__name__': '__main__',
'__doc__': None,
'__package__': None,
'__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001D2863FBF20>,
'__spec__': None,
'__annotations__': {},
'__builtins__': <module 'builtins' (built-in)>,
'__file__': 'D:\\550W\\test.py',
'__cached__': None,
'a': <class '__main__.a'>,
'b': 2,
'n': <function n at 0x000001D2864FCCC0>
}
非常好理解吧?前面一堆下划线是Python解释时自带的,暂且不用管,而Mod_Path创建的变量空间是
{}
正常的Mod是可以执行Tools.py里的东西的,而这样,是无法运行的,怎么办呢?需要加入ToolsGlobal ToolsGlobal(注意,不一定长这样,不要复制这里的内容,它是依靠内存地址显示的):
{
'__name__': '__main__',
'__doc__': None,
'__package__': None,
'__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001FEDDC6BF20>,
'__spec__': None,
'__annotations__': {
},
'__builtins__': <module 'builtins' (built-in)>,
'__file__': 'D:\\550W\\tools.py',
'__cached__': None,
'ttk': <module 'tkinter.ttk' from 'C:\\Program Files\\Python312\\Lib\\tkinter\\ttk.py'>,
'tk': <module 'tkinter' from 'C:\\Program Files\\Python312\\Lib\\tkinter\\__init__.py'>,
'sys': <module 'sys' (built-in)>,
'os': <module 'os' (frozen)>,
'configparser': <module 'configparser' from 'C:\\Program Files\\Python312\\Lib\\configparser.py'>,
'binascii': <module 'binascii' (built-in)>,
'Thread': <class 'threading.Thread'>,
'subprocess': <module 'subprocess' from 'C:\\Program Files\\Python312\\Lib\\subprocess.py'>,
'datetime': <module 'datetime' from 'C:\\Program Files\\Python312\\Lib\\datetime.py'>,
'time': <module 'time' (built-in)>,
'temp': 'C:\\Users\\Lenovo\\AppData\\Local\\Temp',
'openw': <function openw at 0x000001FEDDDAE3E0>,
'opena': <function opena at 0x000001FEDE2368E0>,
'openr': <function openr at 0x000001FEDFDFE0C0>,
'ReturnFileNotFoundError': <function ReturnFileNotFoundError at 0x000001FEDFDFF4C0>,
'IS_INI': <function IS_INI at 0x000001FEDFDFF560>,
'INI2DICT': <function INI2DICT at 0x000001FEDFDFF600>,
'CreateMod': <function CreateMod at 0x000001FEDFDFF6A0>,
'GetMod': <function GetMod at 0x000001FEDFDFF740>,
'InFo': <class '__main__.InFo'>,
'asyncs': <function asyncs at 0x000001FEDFDFF7E0>,
'Mod': <class '__main__.Mod'>,
'Mod_Path': <class '__main__.Mod_Path'>,
}
这样,我们就能够写出这样的代码(Module/Test/Main.py):
from App import *
a_path=Mod_Path()
b_path=Mod_Path()
a_path.Global=dict(a_path.Global,**ToolsGlobal)
b_path.Global=dict(b_path.Global,**ToolsGlobal)
非常简单,那./Main.py怎么写呢?
#550W Manned Orbital Space Station Operating System
#550W/M O S S
from tools import *
os.chdir(os.path.dirname(os.path.realpath(sys.argv[0])))#转到当下
GlobalVariables=globals()
Version=Mod(GlobalVariables,"Test")
Version.RunMain()
那我们就要补全Module/Test/Main.py了
from App import *
a_path=Mod_Path()
b_path=Mod_Path()
a_path.Global=dict(a_path.Global,**ToolsGlobal)
b_path.Global=dict(b_path.Global,**ToolsGlobal)
Mod_InFo.RunSub(a_path.Global,"1.py")
Mod_InFo.RunSub(b_path.Global,"2.py")
这里我们把创建了两个变量空间,并把ToolsGlobal添加到变量空间里,并启动了两个从模块
注意一下啊,我们要使用连贯数据的时候,就比如
from App import *
GET=123456789
a_path=Mod_Path()
a_path.Global=dict(a_path.Global,**ToolsGlobal)
Mod_InFo.RunSub(a_path.Global,"1.py")
我现在想要用从模块获取GET,但是变量空间了没有,有一种方法可以帮你(错的): 错误示例:
from App import *
GET=123456789
a_path=globals()
Mod_InFo.RunSub(a_path.Global,"1.py")
实际上,如果你这么写的话,完全没有问题,因为这个globals()就是获取当前位置所有的变量组成的变量空间,但是,如果1.py对变量组有任何更改的话,更改会同步到Mod的变量空间Main.py,你可能会想,没问题啊,随便,我要的就是这个效果,但是,Module为了让你能操控Module,会设置一个Mod_InFo类,就比如RunSub,而这么做会用1.py的Mod_InFo替换掉Main.py的Mod_Info,你可能会说没有大碍,但是覆盖后1.py的Mod_InFo没有RunSub(权限不足),你必须使用Tools提供的Mod_Path创建变量空间
注意: 命名任何文件不能使用__init__
第三部分 使用Mod_InFo
当我们需要调用Mod中的文件时,我们不能使用绝对路径,因为我们也不知道Mod的绝对路径在哪里。因此我们需要调用Mod_InFo.Path,Mod_InFo.Path本身实际上是Mod的绝对路径,但是会由控制程序进行变化。Mod_InFo.Path的后面有"/",所以你可以用"+"和路径直接调用,下面是一个简单的示例
from App import *
print(tools.openr(Mod_InFo.path+"config.ini"))
在上面的这个程序中,我们通过Mod_InFo.Path+"config.ini"读取到了当前Mod的设置,但实际上,Mod_InFo还有更多功能,这是它的定义过程
#把Mod启动类添加到Global里面
#创建信息类
Mod_InFo=InFo()
#把数据存到信息类
Mod_InFo.path=self.path
Mod_InFo.path_config=self.path_config
Mod_InFo.config=self.config
Mod_InFo.Entry=self.Entry
Mod_InFo.Decode=self.Decode
Mod_InFo.Library=self.Library
Mod_InFo.code=code
Mod_InFo.RunSub=self.RunSub
Mod_InFo.file=self.path+self.Library+name
Mod_InFo.Global=self.Global
#存到Global
GlobalVariables["Mod_InFo"]=Mod_InFo
由此可见Mod_InFo实质上只是一个装有数据的tools.InFo类,而其中包含着许多的内容,如下是对其的解释
| 类 | 解释 | 类型 |
|---|---|---|
| Mod_Info.path | Mod的绝对或相对路径 | <class 'str'> |
| Mod_Info.path_config | Mod的config.ini的绝对或相对路径 | <class 'str'> |
| Mod_Info.config | Mod的设置(config.ini的内容),已字典化 | <class 'dict'> |
| Mod_Info.Entry | Mod的入口(Main)文件的绝对或相对路径 | <class 'str'> |
| Mod_Info.Decode | Mod的加密方式,为"Python"时,直接读取,为"mod"时,使用tools.GBDS解密算法解密 | <class 'str'> |
| Mod_Info.Library | Mod的库文件夹的绝对或相对路径 | <class 'str'> |
| Mod_Info.code | 当前正在运行的文件的代码 | <class 'str'> |
| Mod_Info.RunSub | 函数,用于启动处于库文件夹中的子Mod | <class 'function'> |
| Mod_Info.file | 启动子模块时出现,当前正在启动的子Mod的绝对或相对路径 | <class 'str'> |
| Mod_Info.Global | 当前Mod的变量空间 | <class 'dict'> |
第四部分 高级语法
多模块互通
首先假设我们有两个模块,然后我们在主文件中先后启动: /Main.py
#550W Manned Orbital Space Station Operating System - Test
#550W/M O S S
from tools import *
os.chdir(os.path.dirname(os.path.realpath(sys.argv[0])))#转到当下
GlobalVariables=globals()
Test1=Mod(GlobalVariables,"Test1")
Test1.RunMain()
Test2=Mod(GlobalVariables,"Test2")
Test2.RunMain()
两个Mod的目录:
| 第一层目录 | 第二层目录 | 第三层目录 |
|---|---|---|
| Module/ | Test1/ | Config.ini |
| Lib/ | ||
| Main.py | ||
| Module/ | Test2/ | Config.ini |
| Lib/ | ||
| Main.py |
两个Mod的Config.ini都是
[CONFIG]
ENTRY=Main.py
DECODE=Python
LIBRARY=Lib
在第一个Mod(Test1)中,我们定义一个叫做test1value的变量,并赋值为int(1)
/Module/Test1/Main.py
from App import *
test1value=1#int(1)
那么,在Test2中,我们该如何获取test1value中的信息呢?需要使用如下代码 /Module/Test2/Main.py
from App import *
test1global=Mod_InFo.Global
test1value=test1global["test1value"]
通过这种方法就可以在Test2中获得Test1中的test1value