How_To_Build_The_First_SYS

本文详细介绍了如何使用Windows Driver Kit (WDK) 7.0搭建和编译第一个驱动程序,从编写hello.c源代码、设置makefile和sources文件到最终安装并运行内核驱动,包括安装服务、启动和结束服务的过程。
 

Introduction

第一个sys。

Details

一、下载WDK7.0 前一个wiki已经讲过了。

二、安装WDK7.0 没什么好说的,完全安装,一路next,但是要注意的是,安装时必须是在光盘里,也就是没有光盘得用虚拟光驱才能顺利安装(当初我就是这样的- -)。

三、编写第一个驱动代码 这里没什么好说的,直接用《寒江》里的那个hello 文件名:hello.c

#include <ntddk .h> 
 
//卸载驱动 
VOID DriverUnload(PDRIVER_OBJECT driver) 
{ 
DbgPrint("first: Driver is unloading…\r\n"); 
} 
 
//入口函数 
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path) 
{ 
 
DbgPrint("first: Hello World!"); 
 
// 设置一个卸载函数指针 
driver->DriverUnload = DriverUnload; 
return STATUS_SUCCESS; 
}

四、编译代码 编译hello.c必须添加2个工程文件,以便于WDK的build工具可以编译它,其中一个文件的名字必须是makefile,而且内容很无聊,永远也不需要改动。 文件名:makefile

!IF 0 
 
Copyright (C) Microsoft Corporation, 1999 - 2002 
 
Module Name: 
 
makefile. 
 
Notes: 
 
DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source 
file to this component. This file merely indirects to the real make file 
that is shared by all the components of Windows NT (DDK) 
 
!ENDIF 
 
!INCLUDE $(NTMAKEENV)\makefile.def

另外还需要一个名字为sources的文件,这个文件的内容关系到这个模块要编译哪些文件,以及编译出来的.sys文件的名字 文件名:sources

TARGETNAME=hello 
TARGETTYPE=DRIVER 
TARGETPATH=obj 
SOURCES=hello.c

TARGETNAME表示名字,编译出来后文件名为hello.sys,sources表示要编译的文件,如果.c文件有多个,请用空格分隔。

将上面2个工程文件添加好了之后,然后在“开始”菜单中打开WDK的Build环境配置。 7.0的位置在 开始->所有程序->Windows Driver Kits->WDK 7600.16385.0->Build Environments->Windows Vista and Windows Server 2008->x86 Checked Build Environment

然后执行cd命令,到我们的hello.c的目录下,然后执行build命令,好了,编译好的hello.sys就在\hello\objchk_wlh_x86\i386\下静静的躺着了。

五、安装内核驱动 1.打开并运行srvinstw.exe(tool文件夹中有) 2.选择"安装服务"->"本地计算机"->输入服务名称(这里我输入的是hello)->输入sys文件的路径(无法浏览,因为filefilter只能让我们选exe) 3.选择"设备驱动"->输入"NT驱动器目标名"(可以不填)->选择启动类型(建议选手动,不然不方便调试)

六、运行和查看输出信息 1.管理员模式运行DebugView,并把Capture->Capture Kernel选上 2.由于前面已经安装了hello.sys,我们这时只需要打开命令提示符,输入net start hello和net stop hello(hello即服务名)来启动和结束服务 3.启动服务我们可以在DebugView中看到相应的内核输出信息 00000000 0.00000000 first: Hello World! 00000001 3.25863314 first: Driver is unloading… (建议在干净的虚拟机里实验)

"""Append module search paths for third-party packages to sys.path. **************************************************************** * This module is automatically imported during initialization. * **************************************************************** This will append site-specific paths to the module search path. On Unix (including Mac OSX), it starts with sys.prefix and sys.exec_prefix (if different) and appends lib/python<version>/site-packages. On other platforms (such as Windows), it tries each of the prefixes directly, as well as with lib/site-packages appended. The resulting directories, if they exist, are appended to sys.path, and also inspected for path configuration files. If a file named "pyvenv.cfg" exists one directory above sys.executable, sys.prefix and sys.exec_prefix are set to that directory and it is also checked for site-packages (sys.base_prefix and sys.base_exec_prefix will always be the "real" prefixes of the Python installation). If "pyvenv.cfg" (a bootstrap configuration file) contains the key "include-system-site-packages" set to anything other than "false" (case-insensitive), the system-level prefixes will still also be searched for site-packages; otherwise they won't. All of the resulting site-specific directories, if they exist, are appended to sys.path, and also inspected for path configuration files. A path configuration file is a file whose name has the form <package>.pth; its contents are additional directories (one per line) to be added to sys.path. Non-existing directories (or non-directories) are never added to sys.path; no directory is added to sys.path more than once. Blank lines and lines beginning with '#' are skipped. Lines starting with 'import' are executed. For example, suppose sys.prefix and sys.exec_prefix are set to /usr/local and there is a directory /usr/local/lib/python2.5/site-packages with three subdirectories, foo, bar and spam, and two path configuration files, foo.pth and bar.pth. Assume foo.pth contains the following: # foo package configuration foo bar bletch and bar.pth contains: # bar package configuration bar Then the following directories are added to sys.path, in this order: /usr/local/lib/python2.5/site-packages/bar /usr/local/lib/python2.5/site-packages/foo Note that bletch is omitted because it doesn't exist; bar precedes foo because bar.pth comes alphabetically before foo.pth; and spam is omitted because it is not mentioned in either path configuration file. The readline module is also automatically configured to enable completion for systems that support it. This can be overridden in sitecustomize, usercustomize or PYTHONSTARTUP. Starting Python in isolated mode (-I) disables automatic readline configuration. After these operations, an attempt is made to import a module named sitecustomize, which can perform arbitrary additional site-specific customizations. If this import fails with an ImportError exception, it is silently ignored. """ import sys import os import builtins import _sitebuiltins import io import stat import errno # Prefixes for site-packages; add additional prefixes like /usr/local here PREFIXES = [sys.prefix, sys.exec_prefix] # Enable per user site-packages directory # set it to False to disable the feature or True to force the feature ENABLE_USER_SITE = None # for distutils.commands.install # These values are initialized by the getuserbase() and getusersitepackages() # functions, through the main() function when Python starts. USER_SITE = None USER_BASE = None def _trace(message): if sys.flags.verbose: print(message, file=sys.stderr) def makepath(*paths): dir = os.path.join(*paths) try: dir = os.path.abspath(dir) except OSError: pass return dir, os.path.normcase(dir) def abs_paths(): """Set all module __file__ and __cached__ attributes to an absolute path""" for m in set(sys.modules.values()): loader_module = None try: loader_module = m.__loader__.__module__ except AttributeError: try: loader_module = m.__spec__.loader.__module__ except AttributeError: pass if loader_module not in {'_frozen_importlib', '_frozen_importlib_external'}: continue # don't mess with a PEP 302-supplied __file__ try: m.__file__ = os.path.abspath(m.__file__) except (AttributeError, OSError, TypeError): pass try: m.__cached__ = os.path.abspath(m.__cached__) except (AttributeError, OSError, TypeError): pass def removeduppaths(): """ Remove duplicate entries from sys.path along with making them absolute""" # This ensures that the initial path provided by the interpreter contains # only absolute pathnames, even if we're running from the build directory. L = [] known_paths = set() for dir in sys.path: # Filter out duplicate paths (on case-insensitive file systems also # if they only differ in case); turn relative paths into absolute # paths. dir, dircase = makepath(dir) if dircase not in known_paths: L.append(dir) known_paths.add(dircase) sys.path[:] = L return known_paths def _init_pathinfo(): """Return a set containing all existing file system items from sys.path.""" d = set() for item in sys.path: try: if os.path.exists(item): _, itemcase = makepath(item) d.add(itemcase) except TypeError: continue return d def addpackage(sitedir, name, known_paths): """Process a .pth file within the site-packages directory: For each line in the file, either combine it with sitedir to a path and add that to known_paths, or execute it if it starts with 'import '. """ if known_paths is None: known_paths = _init_pathinfo() reset = True else: reset = False fullname = os.path.join(sitedir, name) try: st = os.lstat(fullname) except OSError: return if ((getattr(st, 'st_flags', 0) & stat.UF_HIDDEN) or (getattr(st, 'st_file_attributes', 0) & stat.FILE_ATTRIBUTE_HIDDEN)): _trace(f"Skipping hidden .pth file: {fullname!r}") return _trace(f"Processing .pth file: {fullname!r}") try: with io.open_code(fullname) as f: pth_content = f.read() except OSError: return try: # Accept BOM markers in .pth files as we do in source files # (Windows PowerShell 5.1 makes it hard to emit UTF-8 files without a BOM) pth_content = pth_content.decode("utf-8-sig") except UnicodeDecodeError: # Fallback to locale encoding for backward compatibility. # We will deprecate this fallback in the future. import locale pth_content = pth_content.decode(locale.getencoding()) _trace(f"Cannot read {fullname!r} as UTF-8. " f"Using fallback encoding {locale.getencoding()!r}") for n, line in enumerate(pth_content.splitlines(), 1): if line.startswith("#"): continue if line.strip() == "": continue try: if line.startswith(("import ", "import\t")): exec(line) continue line = line.rstrip() dir, dircase = makepath(sitedir, line) if dircase not in known_paths and os.path.exists(dir): sys.path.append(dir) known_paths.add(dircase) except Exception as exc: print(f"Error processing line {n:d} of {fullname}:\n", file=sys.stderr) import traceback for record in traceback.format_exception(exc): for line in record.splitlines(): print(' '+line, file=sys.stderr) print("\nRemainder of file ignored", file=sys.stderr) break if reset: known_paths = None return known_paths def addsitedir(sitedir, known_paths=None): """Add 'sitedir' argument to sys.path if missing and handle .pth files in 'sitedir'""" _trace(f"Adding directory: {sitedir!r}") if known_paths is None: known_paths = _init_pathinfo() reset = True else: reset = False sitedir, sitedircase = makepath(sitedir) if not sitedircase in known_paths: sys.path.append(sitedir) # Add path component known_paths.add(sitedircase) try: names = os.listdir(sitedir) except OSError: return names = [name for name in names if name.endswith(".pth") and not name.startswith(".")] for name in sorted(names): addpackage(sitedir, name, known_paths) if reset: known_paths = None return known_paths def check_enableusersite(): """Check if user site directory is safe for inclusion The function tests for the command line flag (including environment var), process uid/gid equal to effective uid/gid. None: Disabled for security reasons False: Disabled by user (command line option) True: Safe and enabled """ if sys.flags.no_user_site: return False if hasattr(os, "getuid") and hasattr(os, "geteuid"): # check process uid == effective uid if os.geteuid() != os.getuid(): return None if hasattr(os, "getgid") and hasattr(os, "getegid"): # check process gid == effective gid if os.getegid() != os.getgid(): return None return True # NOTE: sysconfig and it's dependencies are relatively large but site module # needs very limited part of them. # To speedup startup time, we have copy of them. # # See https://bugs.python.org/issue29585 # Copy of sysconfig._get_implementation() def _get_implementation(): return 'Python' # Copy of sysconfig._getuserbase() def _getuserbase(): env_base = os.environ.get("PYTHONUSERBASE", None) if env_base: return env_base # Emscripten, iOS, tvOS, VxWorks, WASI, and watchOS have no home directories if sys.platform in {"emscripten", "ios", "tvos", "vxworks", "wasi", "watchos"}: return None def joinuser(*args): return os.path.expanduser(os.path.join(*args)) if os.name == "nt": base = os.environ.get("APPDATA") or "~" return joinuser(base, _get_implementation()) if sys.platform == "darwin" and sys._framework: return joinuser("~", "Library", sys._framework, "%d.%d" % sys.version_info[:2]) return joinuser("~", ".local") # Same to sysconfig.get_path('purelib', os.name+'_user') def _get_path(userbase): version = sys.version_info if hasattr(sys, 'abiflags') and 't' in sys.abiflags: abi_thread = 't' else: abi_thread = '' implementation = _get_implementation() implementation_lower = implementation.lower() if os.name == 'nt': ver_nodot = sys.winver.replace('.', '') return f'{userbase}\\{implementation}{ver_nodot}\\site-packages' if sys.platform == 'darwin' and sys._framework: return f'{userbase}/lib/{implementation_lower}/site-packages' return f'{userbase}/lib/python{version[0]}.{version[1]}{abi_thread}/site-packages' def getuserbase(): """Returns the `user base` directory path. The `user base` directory can be used to store data. If the global variable ``USER_BASE`` is not initialized yet, this function will also set it. """ global USER_BASE if USER_BASE is None: USER_BASE = _getuserbase() return USER_BASE def getusersitepackages(): """Returns the user-specific site-packages directory path. If the global variable ``USER_SITE`` is not initialized yet, this function will also set it. """ global USER_SITE, ENABLE_USER_SITE userbase = getuserbase() # this will also set USER_BASE if USER_SITE is None: if userbase is None: ENABLE_USER_SITE = False # disable user site and return None else: USER_SITE = _get_path(userbase) return USER_SITE def addusersitepackages(known_paths): """Add a per user site-package to sys.path Each user has its own python directory with site-packages in the home directory. """ # get the per user site-package path # this call will also make sure USER_BASE and USER_SITE are set _trace("Processing user site-packages") user_site = getusersitepackages() if ENABLE_USER_SITE and os.path.isdir(user_site): addsitedir(user_site, known_paths) return known_paths def getsitepackages(prefixes=None): """Returns a list containing all global site-packages directories. For each directory present in ``prefixes`` (or the global ``PREFIXES``), this function will find its `site-packages` subdirectory depending on the system environment, and will return a list of full paths. """ sitepackages = [] seen = set() if prefixes is None: prefixes = PREFIXES for prefix in prefixes: if not prefix or prefix in seen: continue seen.add(prefix) implementation = _get_implementation().lower() ver = sys.version_info if hasattr(sys, 'abiflags') and 't' in sys.abiflags: abi_thread = 't' else: abi_thread = '' if os.sep == '/': libdirs = [sys.platlibdir] if sys.platlibdir != "lib": libdirs.append("lib") for libdir in libdirs: path = os.path.join(prefix, libdir, f"{implementation}{ver[0]}.{ver[1]}{abi_thread}", "site-packages") sitepackages.append(path) else: sitepackages.append(prefix) sitepackages.append(os.path.join(prefix, "Lib", "site-packages")) return sitepackages def addsitepackages(known_paths, prefixes=None): """Add site-packages to sys.path""" _trace("Processing global site-packages") for sitedir in getsitepackages(prefixes): if os.path.isdir(sitedir): addsitedir(sitedir, known_paths) return known_paths def setquit(): """Define new builtins 'quit' and 'exit'. These are objects which make the interpreter exit when called. The repr of each object contains a hint at how it works. """ if os.sep == '\\': eof = 'Ctrl-Z plus Return' else: eof = 'Ctrl-D (i.e. EOF)' builtins.quit = _sitebuiltins.Quitter('quit', eof) builtins.exit = _sitebuiltins.Quitter('exit', eof) def setcopyright(): """Set 'copyright' and 'credits' in builtins""" builtins.copyright = _sitebuiltins._Printer("copyright", sys.copyright) builtins.credits = _sitebuiltins._Printer("credits", """\ Thanks to CWI, CNRI, BeOpen, Zope Corporation, the Python Software Foundation, and a cast of thousands for supporting Python development. See www.python.org for more information.""") files, dirs = [], [] # Not all modules are required to have a __file__ attribute. See # PEP 420 for more details. here = getattr(sys, '_stdlib_dir', None) if not here and hasattr(os, '__file__'): here = os.path.dirname(os.__file__) if here: files.extend(["LICENSE.txt", "LICENSE"]) dirs.extend([os.path.join(here, os.pardir), here, os.curdir]) builtins.license = _sitebuiltins._Printer( "license", "See https://www.python.org/psf/license/", files, dirs) def sethelper(): builtins.help = _sitebuiltins._Helper() def gethistoryfile(): """Check if the PYTHON_HISTORY environment variable is set and define it as the .python_history file. If PYTHON_HISTORY is not set, use the default .python_history file. """ if not sys.flags.ignore_environment: history = os.environ.get("PYTHON_HISTORY") if history: return history return os.path.join(os.path.expanduser('~'), '.python_history') def enablerlcompleter(): """Enable default readline configuration on interactive prompts, by registering a sys.__interactivehook__. """ sys.__interactivehook__ = register_readline def register_readline(): """Configure readline completion on interactive prompts. If the readline module can be imported, the hook will set the Tab key as completion key and register ~/.python_history as history file. This can be overridden in the sitecustomize or usercustomize module, or in a PYTHONSTARTUP file. """ if not sys.flags.ignore_environment: PYTHON_BASIC_REPL = os.getenv("PYTHON_BASIC_REPL") else: PYTHON_BASIC_REPL = False import atexit try: try: import readline except ImportError: readline = None else: import rlcompleter # noqa: F401 except ImportError: return try: if PYTHON_BASIC_REPL: CAN_USE_PYREPL = False else: original_path = sys.path sys.path = [p for p in original_path if p != ''] try: import _pyrepl.readline if os.name == "nt": import _pyrepl.windows_console console_errors = (_pyrepl.windows_console._error,) else: import _pyrepl.unix_console console_errors = _pyrepl.unix_console._error from _pyrepl.main import CAN_USE_PYREPL finally: sys.path = original_path except ImportError: return if readline is not None: # Reading the initialization (config) file may not be enough to set a # completion key, so we set one first and then read the file. if readline.backend == 'editline': readline.parse_and_bind('bind ^I rl_complete') else: readline.parse_and_bind('tab: complete') try: readline.read_init_file() except OSError: # An OSError here could have many causes, but the most likely one # is that there's no .inputrc file (or .editrc file in the case of # Mac OS X + libedit) in the expected location. In that case, we # want to ignore the exception. pass if readline is None or readline.get_current_history_length() == 0: # If no history was loaded, default to .python_history, # or PYTHON_HISTORY. # The guard is necessary to avoid doubling history size at # each interpreter exit when readline was already configured # through a PYTHONSTARTUP hook, see: # http://bugs.python.org/issue5845#msg198636 history = gethistoryfile() if CAN_USE_PYREPL: readline_module = _pyrepl.readline exceptions = (OSError, *console_errors) else: if readline is None: return readline_module = readline exceptions = OSError try: readline_module.read_history_file(history) except exceptions: pass def write_history(): try: readline_module.write_history_file(history) except (FileNotFoundError, PermissionError): # home directory does not exist or is not writable # https://bugs.python.org/issue19891 pass except OSError: if errno.EROFS: pass # gh-128066: read-only file system else: raise atexit.register(write_history) def venv(known_paths): global PREFIXES, ENABLE_USER_SITE env = os.environ if sys.platform == 'darwin' and '__PYVENV_LAUNCHER__' in env: executable = sys._base_executable = os.environ['__PYVENV_LAUNCHER__'] else: executable = sys.executable exe_dir = os.path.dirname(os.path.abspath(executable)) site_prefix = os.path.dirname(exe_dir) sys._home = None conf_basename = 'pyvenv.cfg' candidate_conf = next( ( conffile for conffile in ( os.path.join(exe_dir, conf_basename), os.path.join(site_prefix, conf_basename) ) if os.path.isfile(conffile) ), None ) if candidate_conf: virtual_conf = candidate_conf system_site = "true" # Issue 25185: Use UTF-8, as that's what the venv module uses when # writing the file. with open(virtual_conf, encoding='utf-8') as f: for line in f: if '=' in line: key, _, value = line.partition('=') key = key.strip().lower() value = value.strip() if key == 'include-system-site-packages': system_site = value.lower() elif key == 'home': sys._home = value sys.prefix = sys.exec_prefix = site_prefix # Doing this here ensures venv takes precedence over user-site addsitepackages(known_paths, [sys.prefix]) # addsitepackages will process site_prefix again if its in PREFIXES, # but that's ok; known_paths will prevent anything being added twice if system_site == "true": PREFIXES.insert(0, sys.prefix) else: PREFIXES = [sys.prefix] ENABLE_USER_SITE = False return known_paths def execsitecustomize(): """Run custom site specific code, if available.""" try: try: import sitecustomize except ImportError as exc: if exc.name == 'sitecustomize': pass else: raise except Exception as err: if sys.flags.verbose: sys.excepthook(*sys.exc_info()) else: sys.stderr.write( "Error in sitecustomize; set PYTHONVERBOSE for traceback:\n" "%s: %s\n" % (err.__class__.__name__, err)) def execusercustomize(): """Run custom user specific code, if available.""" try: try: import usercustomize except ImportError as exc: if exc.name == 'usercustomize': pass else: raise except Exception as err: if sys.flags.verbose: sys.excepthook(*sys.exc_info()) else: sys.stderr.write( "Error in usercustomize; set PYTHONVERBOSE for traceback:\n" "%s: %s\n" % (err.__class__.__name__, err)) def main(): """Add standard site-specific directories to the module search path. This function is called automatically when this module is imported, unless the python interpreter was started with the -S flag. """ global ENABLE_USER_SITE orig_path = sys.path[:] known_paths = removeduppaths() if orig_path != sys.path: # removeduppaths() might make sys.path absolute. # fix __file__ and __cached__ of already imported modules too. abs_paths() known_paths = venv(known_paths) if ENABLE_USER_SITE is None: ENABLE_USER_SITE = check_enableusersite() known_paths = addusersitepackages(known_paths) known_paths = addsitepackages(known_paths) setquit() setcopyright() sethelper() if not sys.flags.isolated: enablerlcompleter() execsitecustomize() if ENABLE_USER_SITE: execusercustomize() # Prevent extending of sys.path when python was started with -S and # site is imported later. if not sys.flags.no_site: main() def _script(): help = """\ %s [--user-base] [--user-site] Without arguments print some useful information With arguments print the value of USER_BASE and/or USER_SITE separated by '%s'. Exit codes with --user-base or --user-site: 0 - user site directory is enabled 1 - user site directory is disabled by user 2 - user site directory is disabled by super user or for security reasons >2 - unknown error """ args = sys.argv[1:] if not args: user_base = getuserbase() user_site = getusersitepackages() print("sys.path = [") for dir in sys.path: print(" %r," % (dir,)) print("]") def exists(path): if path is not None and os.path.isdir(path): return "exists" else: return "doesn't exist" print(f"USER_BASE: {user_base!r} ({exists(user_base)})") print(f"USER_SITE: {user_site!r} ({exists(user_site)})") print(f"ENABLE_USER_SITE: {ENABLE_USER_SITE!r}") sys.exit(0) buffer = [] if '--user-base' in args: buffer.append(USER_BASE) if '--user-site' in args: buffer.append(USER_SITE) if buffer: print(os.pathsep.join(buffer)) if ENABLE_USER_SITE: sys.exit(0) elif ENABLE_USER_SITE is False: sys.exit(1) elif ENABLE_USER_SITE is None: sys.exit(2) else: sys.exit(3) else: import textwrap print(textwrap.dedent(help % (sys.argv[0], os.pathsep))) sys.exit(10) if __name__ == '__main__': _script()
08-29
你提供的是一段 Python 的内置模块 `site.py` 的完整源码,这段代码负责在 Python 启动时**自动配置模块搜索路径(sys.path)**,并处理与 Python 环境相关的初始化逻辑。 --- ## ✅ 作用简述 `site.py` 是 Python 启动时自动导入的一个核心模块,它的主要职责是: 1. **设置模块搜索路径 `sys.path`** 2. **处理虚拟环境(venv)的路径配置** 3. **添加用户和系统级的 `site-packages` 目录** 4. **执行 `.pth` 文件(路径配置文件)** 5. **启用 `readline` 的 Tab 自动补全功能** 6. **设置内置命令 `quit()`、`exit()`、`help()`、`copyright` 等** --- ## 📌 模块功能详解 ### 1. **路径去重和绝对化:`removeduppaths()`** ```python removeduppaths() ``` 作用:去除 `sys.path` 中的重复路径,并将所有路径转换为绝对路径。 --- ### 2. **添加全局 site-packages:`addsitepackages()`** ```python addsitepackages(known_paths) ``` 作用:遍历系统前缀(如 `/usr/local`, `C:\Python39`)下的 `site-packages` 目录,并将它们添加到 `sys.path` 中。 --- ### 3. **添加用户 site-packages:`addusersitepackages()`** ```python addusersitepackages(known_paths) ``` 作用:如果启用了用户级安装(`--user` 安装的包),则将用户目录下的 `site-packages` 添加到模块路径中。 --- ### 4. **处理虚拟环境:`venv()`** ```python venv(known_paths) ``` 作用:检查是否处于虚拟环境(通过 `pyvenv.cfg` 文件判断),并相应地设置 `sys.prefix` 和路径优先级。 --- ### 5. **执行路径配置文件:`.pth` 文件** ```python addpackage(sitedir, name, known_paths) ``` 作用:处理 `.pth` 文件中的路径或导入语句,动态扩展模块搜索路径。 --- ### 6. **设置内置命令:`setquit()`、`setcopyright()`、`sethelper()`** ```python setquit() setcopyright() sethelper() ``` 作用:定义 `quit()`、`exit()`、`copyright`、`credits`、`license`、`help()` 等交互式命令。 --- ### 7. **启用 Tab 自动补全:`enablerlcompleter()`** ```python enablerlcompleter() ``` 作用:在交互式解释器中启用 `Tab` 键自动补全功能。 --- ### 8. **执行自定义脚本:`execsitecustomize()` 和 `execusercustomize()`** ```python execsitecustomize() execusercustomize() ``` 作用:尝试导入 `sitecustomize` 和 `usercustomize` 模块,用于进行自定义初始化操作。 --- ## 🧠 示例:`.pth` 文件的作用 假设你在 `site-packages` 目录下有一个文件 `mylib.pth`,内容如下: ``` # 添加额外的模块路径 /my/custom/modules # 执行任意 Python 代码 import sys; sys.path.append("/another/custom/path") ``` `site.py` 在启动时会读取这个 `.pth` 文件,并执行其中的内容,从而动态扩展模块路径。 --- ## 🧪 如何查看当前的模块搜索路径? 你可以运行以下代码查看当前的 `sys.path`: ```python import sys print(sys.path) ``` 输出示例: ``` ['', '/usr/lib/python3.9', '/usr/lib/python3.9/lib-dynload', '/home/user/.local/lib/python3.9/site-packages', '/usr/local/lib/python3.9/dist-packages', ... ] ``` --- ## ✅ 总结 | 功能 | 方法 | 说明 | |------|------|------| | 去重路径 | `removeduppaths()` | 清理 `sys.path` | | 添加全局包 | `addsitepackages()` | 加载系统级 `site-packages` | | 添加用户包 | `addusersitepackages()` | 加载 `~/.local/lib/pythonX.X/site-packages` | | 虚拟环境支持 | `venv()` | 处理 venv 的路径配置 | | `.pth` 文件处理 | `addpackage()` | 动态扩展路径或执行代码 | | 设置内置命令 | `setquit()`、`sethelper()` 等 | 启用交互命令 | | Tab 自动补全 | `enablerlcompleter()` | 启用 readline 补全 | | 自定义初始化 | `execsitecustomize()` / `execusercustomize()` | 加载自定义模块 | --- ##
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值