5C# Null 条件运算符

在 C# 编程中,处理 null 值是一个常见但又容易出错的任务。

传统的 null 检查代码往往冗长且繁琐,而 C# 6.0 引入的 Null 条件运算符?. 和 ?[])极大地简化了这一过程。

Null 条件运算符是 C# 6.0 引入的一个语法糖,它允许开发者在访问对象的成员或元素之前,先检查该对象是否为 null。如果对象为 null,则整个表达式的结果为 null,而不会抛出 NullReferenceException

基本语法

  • ?. - 用于访问成员(属性、方法、字段)
  • ?[] - 用于访问索引器或数组元素
语法说明
a?.b如果 a 不为 null,则访问 a.b;否则返回 null
a?.Method()如果 a 不为 null,则调用方法;否则什么都不做
a?[i]如果 a 不为 null,则访问索引;否则返回 null

为什么需要 Null 条件运算符?

传统 null 检查的问题

在 Null 条件运算符出现之前,开发者需要编写冗长的 null 检查代码:

实例

// 传统方式 - 繁琐的 null 检查
string name = null;
if (person != null)
{
    if (person.Address != null)
    {
        if (person.Address.City != null)
        {
            name = person.Address.City.Name;
        }
    }
}

这种代码不仅冗长,而且容易出错,可读性也较差。

Null 条件运算符的优势

使用 Null 条件运算符,同样的逻辑可以简化为:

// 使用 Null 条件运算符 - 简洁明了
string name = person?.Address?.City?.Name;

如果链式调用中的任何一个环节为 null,整个表达式就会返回 null,而不会抛出异常。


详细语法说明

1. 成员访问运算符 ?.

?. 运算符用于安全地访问对象的成员(属性、方法、字段)。

访问属性

实例

class Person
{
    public string Name { get; set; }
    public Address Address { get; set; }
}

class Address
{
    public string City { get; set; }
}

// 安全访问属性
Person person = null;
string cityName = person?.Address?.City;  // 返回 null,不会抛出异常

调用方法

实例

class Calculator
{
    public int Add(int a, int b) => a + b;
}

Calculator calc = null;
int? result = calc?.Add(5, 3);  // 返回 null,不会抛出异常

访问字段

实例

class DataContainer
{
    public string Value;
}

DataContainer container = null;
string value = container?.Value;  // 返回 null,不会抛出异常

2. 元素访问运算符 ?[]

?[] 运算符用于安全地访问数组或集合的元素。

访问数组元素

实例

int[] numbers = null;
int? firstNumber = numbers?[0];  // 返回 null,不会抛出异常

numbers = new int[] { 1, 2, 3 };
firstNumber = numbers?[0];  // 返回 1

访问字典元素

实例

Dictionary<string, string> dictionary = null;
string value = dictionary?["key"];  // 返回 null,不会抛出异常

dictionary = new Dictionary<string, string> { ["key"] = "value" };
value = dictionary?["key"];  // 返回 "value"


与其它运算符的组合使用

运算符名称用途示例返回值
?可空类型声明声明可以为 null 的值类型int? x = null;null
??Null 合并运算符如果左侧为 null,返回右侧a ?? bb
?.Null 条件运算符安全访问成员a?.bnull 或 b 的值
?[]Null 条件索引运算符安全访问数组或集合a?[i]null 或元素
?:条件(三元)运算符根据条件返回不同值a ? b : cb 或 c

1. 与 Null 合并运算符 ?? 结合

Null 条件运算符经常与 Null 合并运算符 ?? 一起使用,提供默认值:

Person person = null;

// 提供默认值
string cityName = person?.Address?.City ?? "未知城市";
Console.WriteLine(cityName);  // 输出: 未知城市

person = new Person { Address = new Address { City = "北京" } };
cityName = person?.Address?.City ?? "未知城市";
Console.WriteLine(cityName);  // 输出: 北京

实例

using System;

class Address
{
    public string City { get; set; }
}

class Person
{
    public string Name { get; set; }
    public Address Address { get; set; }

    public void SayHello()
    {
        Console.WriteLine($"你好,我是 {Name}");
    }
}

class Program
{
    static void Main()
    {
        Person person = null;

        // 安全访问属性
        Console.WriteLine(person?.Name ?? "未命名用户");

        // 安全访问嵌套属性
        Console.WriteLine(person?.Address?.City ?? "未知城市");

        // 安全调用方法
        person?.SayHello();

        // 安全访问数组
        int[] arr = null;
        Console.WriteLine(arr?[0] ?? -1);
    }
}

输出:

未命名用户
未知城市
-1

2. 与条件运算符 ?: 结合

实例

Person person = null;
string displayName = person?.Name ?? (person != null ? "匿名用户" : "用户不存在");

3. 在 LINQ 查询中使用

实例

List<Person> people = new List<Person>
{
    new Person { Name = "张三", Address = new Address { City = "北京" } },
    new Person { Name = "李四", Address = null },
    null
};

// 安全地访问可能为 null 的属性
var cities = people
    .Where(p => p?.Address?.City != null)
    .Select(p => p.Address.City)
    .ToList();


实际应用场景

场景 1:数据绑定和 UI 开发

实例

// 在 WPF 或 ASP.NET 中安全地绑定数据
public string DisplayAddress => $"{Person?.Address?.City ?? "未知城市"} - {Person?.Address?.Street ?? "未知街道"}";

// 安全地调用方法
button.Click += (s, e) =>
{
    viewModel?.SaveCommand?.Execute(null);
};

场景 2:API 响应处理

实例

public class ApiResponse<T>
{
    public T Data { get; set; }
    public string Error { get; set; }
}

public class User
{
    public string Name { get; set; }
    public Profile Profile { get; set; }
}

public class Profile
{
    public string AvatarUrl { get; set; }
}

// 安全地处理 API 响应
ApiResponse<User> response = GetUserFromApi();
string avatarUrl = response?.Data?.Profile?.AvatarUrl ?? "default-avatar.png";

场景 3:配置读取

实例

public class AppConfig
{
    public DatabaseConfig Database { get; set; }
}

public class DatabaseConfig
{
    public string ConnectionString { get; set; }
    public int? Timeout { get; set; }
}

// 安全读取配置
AppConfig config = LoadConfiguration();
string connectionString = config?.Database?.ConnectionString ?? "DefaultConnection";
int timeout = config?.Database?.Timeout ?? 30;


注意事项和最佳实践

1. 返回值类型

使用 Null 条件运算符时,需要注意表达式的返回类型:

实例

Person person = new Person { Name = "张三" };

// 对于值类型,返回 Nullable<T>
int? nameLength = person?.Name?.Length;  // 类型是 int?

// 对于引用类型,返回类型本身
string name = person?.Name;  // 类型是 string

2. 避免过度使用

虽然 Null 条件运算符很方便,但不应过度使用:

实例

// 不推荐 - 过度使用,难以理解
var result = obj1?.Property1?.Method1()?.Property2 ?? defaultValue;

// 推荐 - 适当分解,提高可读性
var temp1 = obj1?.Property1;
var temp2 = temp1?.Method1();
var result = temp2?.Property2 ?? defaultValue;

3. 性能考虑

Null 条件运算符在性能上与显式的 null 检查相当,但链式调用会创建临时变量:

实例

// 这两种方式性能相当
// 方式 1: 传统检查
if (person != null && person.Address != null)
{
    return person.Address.City;
}

// 方式 2: Null 条件运算符
return person?.Address?.City;

4. 与事件调用结合

Null 条件运算符特别适合用于事件调用:

实例

// 传统方式
public event EventHandler SomethingHappened;

protected virtual void OnSomethingHappened()
{
    if (SomethingHappened != null)
    {
        SomethingHappened(this, EventArgs.Empty);
    }
}

// 使用 Null 条件运算符 - 更简洁
protected virtual void OnSomethingHappened()
{
    SomethingHappened?.Invoke(this, EventArgs.Empty);
}


实践练习

练习 1:重构代码

将以下传统 null 检查代码重构为使用 Null 条件运算符:

实例

// 原始代码
public string GetUserEmail(User user)
{
    if (user != null)
    {
        if (user.Profile != null)
        {
            if (user.Profile.ContactInfo != null)
            {
                return user.Profile.ContactInfo.Email;
            }
        }
    }
    return "无邮箱信息";
}

// 你的重构代码
public string GetUserEmail(User user)
{
    return user?.Profile?.ContactInfo?.Email ?? "无邮箱信息";
}

练习 2:处理集合数据

实例

public class Order
{
    public List<OrderItem> Items { get; set; }
    public Customer Customer { get; set; }
}

public class OrderItem
{
    public Product Product { get; set; }
    public int Quantity { get; set; }
}

public class Product
{
    public string Name { get; set; }
    public decimal Price { get; set; }
}

public class Customer
{
    public string Name { get; set; }
}

// 编写一个方法,安全地获取订单中第一个商品的名字
public string GetFirstProductName(Order order)
{
    return order?.Items?.FirstOrDefault()?.Product?.Name ?? "无商品信息";
}

练习 3:综合应用

实例

// 创建一个完整的示例,演示 Null 条件运算符在实际项目中的应用
public class ShoppingCart
{
    public List<CartItem> Items { get; set; }
    public decimal? CalculateTotal()
    {
        return Items?.Sum(item => item?.Product?.Price * item?.Quantity) ?? 0;
    }
}

public class CartItem
{
    public Product Product { get; set; }
    public int? Quantity { get; set; }
}

Public 访问修饰符

Public 访问修饰符允许一个类将其成员变量和成员函数暴露给其他的函数和对象。任何公有成员可以被外部的类访问。

下面的实例说明了这点:

实例

using System;

namespace RectangleApplication
{
    class Rectangle
    {
        //成员变量
        public double length;
        public double width;

        public double GetArea()
        {
            return length * width;
        }
        public void Display()
        {
            Console.WriteLine("长度: {0}", length);
            Console.WriteLine("宽度: {0}", width);
            Console.WriteLine("面积: {0}", GetArea());
        }
    }// Rectangle 结束

    class ExecuteRectangle
    {
        static void Main(string[] args)
        {
            Rectangle r = new Rectangle();
            r.length = 4.5;
            r.width = 3.5;
            r.Display();
            Console.ReadLine();
        }
    }
}

当上面的代码被编译和执行时,它会产生下列结果:

长度: 4.5
宽度: 3.5
面积: 15.75

在上面的实例中,成员变量 length 和 width 被声明为 public,所以它们可以被函数 Main() 使用 Rectangle 类的实例 r 访问。

成员函数 Display() 和 GetArea() 可以直接访问这些变量。

成员函数 Display() 也被声明为 public,所以它也能被 Main() 使用 Rectangle 类的实例 r 访问。

PS C:\Users\Administrator\Desktop> # 检查 PowerShell 7 安装路径 PS C:\Users\Administrator\Desktop> $pwshPath = "$env:ProgramFiles\PowerShell\7\pwsh.exe" PS C:\Users\Administrator\Desktop> Test-Path $pwshPath False PS C:\Users\Administrator\Desktop> PS C:\Users\Administrator\Desktop> # 检查版本 PS C:\Users\Administrator\Desktop> & $pwshPath -Command { $PSVersionTable } & : 无法将“C:\Program Files\PowerShell\7\pwsh.exe”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。 所在位置 行:1 字符: 3 + & $pwshPath -Command { $PSVersionTable } + ~~~~~~~~~ + CategoryInfo : ObjectNotFound: (C:\Program Files\PowerShell\7\pwsh.exe:String) [], CommandNotFoundExcep tion + FullyQualifiedErrorId : CommandNotFoundException PS C:\Users\Administrator\Desktop> # 创建 PowerShell 7 专用配置文件 PS C:\Users\Administrator\Desktop> $pwshProfile = "$env:USERPROFILE\Documents\PowerShell\Microsoft.PowerShell_profile.ps1" PS C:\Users\Administrator\Desktop> if (-not (Test-Path $pwshProfile)) { >> New-Item -Path $pwshProfile -ItemType File -Force >> } PS C:\Users\Administrator\Desktop> PS C:\Users\Administrator\Desktop> # 添加基础配置 PS C:\Users\Administrator\Desktop> @' >> # 启用现代语法 >> Set-StrictMode -Version 3.0 >> >> # 自定义函数 >> function Invoke-Analyzer { & "E:\DesktopAnalyzer.ps1" } >> function Invoke-Verifier { & "E:\PythonEnvVerifier.ps1" } >> >> function Clean-Desktop { >> $desktopPath = [Environment]::GetFolderPath("Desktop") >> $items = @("myenv", "PythonTools", "path_diagnostic.py", "PythonEnvRepair*") >> >> $removedCount = 0 >> foreach ($item in $items) { >> $path = Join-Path $desktopPath $item >> if (Test-Path $path) { >> Remove-Item $path -Recurse -Force -ErrorAction SilentlyContinue >> $removedCount++ >> } >> } >> >> Write-Host "清理完成: 已删除 $removedCount 个项目" -ForegroundColor Green >> } >> >> # 别名设置 >> Set-Alias da Invoke-Analyzer >> Set-Alias ve Invoke-Verifier >> Set-Alias clean Clean-Desktop >> >> # 提示信息 >> Write-Host "PowerShell 7 环境已加载 (版本: $($PSVersionTable.PSVersion))" -ForegroundColor Cyan >> '@ | Set-Content -Path $pwshProfile -Encoding UTF8 PS C:\Users\Administrator\Desktop> # 创建快捷方式 PS C:\Users\Administrator\Desktop> $shortcutPath = "$env:USERPROFILE\Desktop\PowerShell 7.lnk" PS C:\Users\Administrator\Desktop> $WshShell = New-Object -ComObject WScript.Shell PS C:\Users\Administrator\Desktop> $shortcut = $WshShell.CreateShortcut($shortcutPath) PS C:\Users\Administrator\Desktop> $shortcut.TargetPath = "$env:ProgramFiles\PowerShell\7\pwsh.exe" PS C:\Users\Administrator\Desktop> $shortcut.Arguments = "-NoExit -Command `". `'$pwshProfile`'`"" PS C:\Users\Administrator\Desktop> $shortcut.IconLocation = "$env:ProgramFiles\PowerShell\7\assets\Powershell_av_colors.ico" PS C:\Users\Administrator\Desktop> $shortcut.Save() PS C:\Users\Administrator\Desktop> # 确保分析脚本存在 PS C:\Users\Administrator\Desktop> if (-not (Test-Path "E:\DesktopAnalyzer.ps1")) { >> @' >> # 桌面分析脚本内容 >> $desktopPath = [Environment]::GetFolderPath("Desktop") >> Write-Host "`n=== 桌面文件分析报告 ===`n" -ForegroundColor Cyan >> >> $items = Get-ChildItem -Path $desktopPath -Force >> if (-not $items) { >> Write-Host "桌面是空的!" -ForegroundColor Green >> exit >> } >> >> # ... 完整脚本内容 ... >> '@ | Set-Content -Path "E:\DesktopAnalyzer.ps1" -Encoding UTF8 >> } PS C:\Users\Administrator\Desktop> PS C:\Users\Administrator\Desktop> # 确保验证脚本存在 PS C:\Users\Administrator\Desktop> if (-not (Test-Path "E:\PythonEnvVerifier.ps1")) { >> @' >> # 环境验证脚本内容 >> function Verify-Environment { >> # ... 完整脚本内容 ... >> } >> Verify-Environment >> '@ | Set-Content -Path "E:\EnvVerifier.ps1" -Encoding UTF8 >> } PS C:\Users\Administrator\Desktop> # 三元运算符(正确用法) PS C:\Users\Administrator\Desktop> $result = "成功" PS C:\Users\Administrator\Desktop> Write-Host "检测结果: $result" -ForegroundColor ($result -eq '成功' ? 'Green' : 'Red') 所在位置 行:1 字符: 63 + ... ite-Host "检测结果: $result" -ForegroundColor ($result -eq '成功' ? 'Green' ... + ~ 表达式或语句中包含意外的标记“?”。 所在位置 行:1 字符: 62 + Write-Host "检测结果: $result" -ForegroundColor ($result -eq '成功' ? 'Gree ... + ~ 表达式中缺少右“)”。 所在位置 行:1 字符: 80 + ... "检测结果: $result" -ForegroundColor ($result -eq '成功' ? 'Green' : 'Red') + ~ 表达式或语句中包含意外的标记“)”。 + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : UnexpectedToken PS C:\Users\Administrator\Desktop> PS C:\Users\Administrator\Desktop> # 空值合并运算符 PS C:\Users\Administrator\Desktop> $envVar = $null PS C:\Users\Administrator\Desktop> Write-Host "PYTHONPATH: $($envVar ?? '未设置')" 所在位置 行:1 字符: 35 + Write-Host "PYTHONPATH: $($envVar ?? '未设置')" + ~~ 表达式或语句中包含意外的标记“??”。 + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : UnexpectedToken PS C:\Users\Administrator\Desktop> PS C:\Users\Administrator\Desktop> # 管道链运算符 PS C:\Users\Administrator\Desktop> Get-ChildItem *.py | ForEach-Object { "Python文件: $($_.Name)" } Python文件: test_module.py Python文件: verify_path.py PS C:\Users\Administrator\Desktop> PS C:\Users\Administrator\Desktop> # 简化的错误处理 PS C:\Users\Administrator\Desktop> try { >> Get-Item "C:\不存在路径" -ErrorAction Stop >> } catch { >> Write-Host "错误: $_" -ForegroundColor Red >> } 错误: 找不到路径“C:\不存在路径”,因为该路径不存在。 PS C:\Users\Administrator\Desktop> PS C:\Users\Administrator\Desktop> # 类定义(PowerShell 5+) PS C:\Users\Administrator\Desktop> class FileInfo { >> [string]$Name >> [datetime]$Modified >> [double]$SizeKB >> 所在位置 行:4 字符: 5 + [double]$SizeKB + ~~~~~~~~~~~~~~~ 语句块或类型定义中缺少右“}”。 + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : MissingEndCurlyBrace PS C:\Users\Administrator\Desktop> FileInfo([System.IO.FileInfo]$file) { >> $this.Name = $file.Name >> $this.Modified = $file.LastWriteTime >> $this.SizeKB = [math]::Round($file.Length / 1KB, 2) >> } FileInfo : 无法将“FileInfo”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。 所在位置 行:1 字符: 5 + FileInfo([System.IO.FileInfo]$file) { + ~~~~~~~~ + CategoryInfo : ObjectNotFound: (FileInfo:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException PS C:\Users\Administrator\Desktop> } 所在位置 行:1 字符: 1 + } + ~ 表达式或语句中包含意外的标记“}”。 + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : UnexpectedToken PS C:\Users\Administrator\Desktop> PS C:\Users\Administrator\Desktop> # 使用类 PS C:\Users\Administrator\Desktop> $files = Get-ChildItem | Where-Object { -not $_.PSIsContainer } | ForEach-Object { >> [FileInfo]::new($_) >> } 找不到类型 [FileInfo]。 所在位置 行:2 字符: 5 + [FileInfo]::new($_) + ~~~~~~~~~~ + CategoryInfo : InvalidOperation: (FileInfo:TypeName) [],RuntimeException + FullyQualifiedErrorId : TypeNotFound 找不到类型 [FileInfo]。 所在位置 行:2 字符: 5 + [FileInfo]::new($_) + ~~~~~~~~~~ + CategoryInfo : InvalidOperation: (FileInfo:TypeName) [],RuntimeException + FullyQualifiedErrorId : TypeNotFound 找不到类型 [FileInfo]。 所在位置 行:2 字符: 5 + [FileInfo]::new($_) + ~~~~~~~~~~ + CategoryInfo : InvalidOperation: (FileInfo:TypeName) [],RuntimeException + FullyQualifiedErrorId : TypeNotFound 找不到类型 [FileInfo]。 所在位置 行:2 字符: 5 + [FileInfo]::new($_) + ~~~~~~~~~~ + CategoryInfo : InvalidOperation: (FileInfo:TypeName) [],RuntimeException + FullyQualifiedErrorId : TypeNotFound 找不到类型 [FileInfo]。 所在位置 行:2 字符: 5 + [FileInfo]::new($_) + ~~~~~~~~~~ + CategoryInfo : InvalidOperation: (FileInfo:TypeName) [],RuntimeException + FullyQualifiedErrorId : TypeNotFound 找不到类型 [FileInfo]。 所在位置 行:2 字符: 5 + [FileInfo]::new($_) + ~~~~~~~~~~ + CategoryInfo : InvalidOperation: (FileInfo:TypeName) [],RuntimeException + FullyQualifiedErrorId : TypeNotFound 找不到类型 [FileInfo]。 所在位置 行:2 字符: 5 + [FileInfo]::new($_) + ~~~~~~~~~~ + CategoryInfo : InvalidOperation: (FileInfo:TypeName) [],RuntimeException + FullyQualifiedErrorId : TypeNotFound 找不到类型 [FileInfo]。 所在位置 行:2 字符: 5 + [FileInfo]::new($_) + ~~~~~~~~~~ + CategoryInfo : InvalidOperation: (FileInfo:TypeName) [],RuntimeException + FullyQualifiedErrorId : TypeNotFound 找不到类型 [FileInfo]。 所在位置 行:2 字符: 5 + [FileInfo]::new($_) + ~~~~~~~~~~ + CategoryInfo : InvalidOperation: (FileInfo:TypeName) [],RuntimeException + FullyQualifiedErrorId : TypeNotFound 找不到类型 [FileInfo]。 所在位置 行:2 字符: 5 + [FileInfo]::new($_) + ~~~~~~~~~~ + CategoryInfo : InvalidOperation: (FileInfo:TypeName) [],RuntimeException + FullyQualifiedErrorId : TypeNotFound 找不到类型 [FileInfo]。 所在位置 行:2 字符: 5 + [FileInfo]::new($_) + ~~~~~~~~~~ + CategoryInfo : InvalidOperation: (FileInfo:TypeName) [],RuntimeException + FullyQualifiedErrorId : TypeNotFound PS C:\Users\Administrator\Desktop> $files | Format-Table Name, Modified, SizeKB PS C:\Users\Administrator\Desktop> # 创建Python虚拟环境 PS C:\Users\Administrator\Desktop> python -m venv "E:\PythonTools\clean_env" PS C:\Users\Administrator\Desktop> PS C:\Users\Administrator\Desktop> # 激活虚拟环境 PS C:\Users\Administrator\Desktop> . "E:\PythonTools\clean_env\Scripts\Activate.ps1" (clean_env) PS C:\Users\Administrator\Desktop> (clean_env) PS C:\Users\Administrator\Desktop> # 检查Python路径 (clean_env) PS C:\Users\Administrator\Desktop> Write-Host "当前Python: $(which python)" which : 无法将“which”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。 所在位置 行:1 字符: 25 + Write-Host "当前Python: $(which python)" + ~~~~~ + CategoryInfo : ObjectNotFound: (which:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException 当前Python: (clean_env) PS C:\Users\Administrator\Desktop> (clean_env) PS C:\Users\Administrator\Desktop> # 在虚拟环境中运行脚本 (clean_env) PS C:\Users\Administrator\Desktop> python -c "import sys; print(sys.path)" ['', 'C:\\Users\\Administrator\\Desktop', 'E:\\Python310\\python310.zip', 'E:\\Python310\\DLLs', 'E:\\Python310\\lib', 'E:\\Python310', 'E:\\PythonTools\\clean_env', 'E:\\PythonTools\\clean_env\\lib\\site-packages'] (clean_env) PS C:\Users\Administrator\Desktop> (clean_env) PS C:\Users\Administrator\Desktop> # 安装依赖 (clean_env) PS C:\Users\Administrator\Desktop> pip install -r "E:\requirements.txt" Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple Collecting flask>=2.0.0 Using cached https://pypi.tuna.tsinghua.edu.cn/packages/ec/f9/7f9263c5695f4bd0023734af91bedb2ff8209e8de6ead162f35d8dc762fd/flask-3.1.2-py3-none-any.whl (103 kB) Collecting python-dotenv Using cached https://pypi.tuna.tsinghua.edu.cn/packages/5f/ed/539768cf28c661b5b068d66d96a2f155c4971a5d55684a514c1a0e0dec2f/python_dotenv-1.1.1-py3-none-any.whl (20 kB) Collecting psutil Using cached https://pypi.tuna.tsinghua.edu.cn/packages/50/1b/6921afe68c74868b4c9fa424dad3be35b095e16687989ebbb50ce4fceb7c/psutil-7.0.0-cp37-abi3-win_amd64.whl (244 kB) Collecting sqlalchemy Downloading https://pypi.tuna.tsinghua.edu.cn/packages/38/2d/bfc6b6143adef553a08295490ddc52607ee435b9c751c714620c1b3dd44d/sqlalchemy-2.0.43-cp310-cp310-win_amd64.whl (2.1 MB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.1/2.1 MB 68.2 MB/s eta 0:00:00 Collecting requests Using cached https://pypi.tuna.tsinghua.edu.cn/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl (64 kB) Collecting flask-sse Downloading https://pypi.tuna.tsinghua.edu.cn/packages/71/83/f9fe86f554a153fdd300fb8027121d508a2177605bd158d967ddd7325948/Flask_SSE-1.0.0-py2.py3-none-any.whl (5.0 kB) Collecting itsdangerous>=2.2.0 Using cached https://pypi.tuna.tsinghua.edu.cn/packages/04/96/92447566d16df59b2a776c0fb82dbc4d9e07cd95062562af01e408583fc4/itsdangerous-2.2.0-py3-none-any.whl (16 kB) Collecting blinker>=1.9.0 Using cached https://pypi.tuna.tsinghua.edu.cn/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl (8.5 kB) Collecting markupsafe>=2.1.1 Using cached https://pypi.tuna.tsinghua.edu.cn/packages/44/06/e7175d06dd6e9172d4a69a72592cb3f7a996a9c396eee29082826449bbc3/MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl (15 kB) Collecting werkzeug>=3.1.0 Using cached https://pypi.tuna.tsinghua.edu.cn/packages/52/24/ab44c871b0f07f491e5d2ad12c9bd7358e527510618cb1b803a88e986db1/werkzeug-3.1.3-py3-none-any.whl (224 kB) Collecting jinja2>=3.1.2 Using cached https://pypi.tuna.tsinghua.edu.cn/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl (134 kB) Collecting click>=8.1.3 Using cached https://pypi.tuna.tsinghua.edu.cn/packages/85/32/10bb5764d90a8eee674e9dc6f4db6a0ab47c8c4d0d83c27f7c39ac415a4d/click-8.2.1-py3-none-any.whl (102 kB) Collecting typing-extensions>=4.6.0 Using cached https://pypi.tuna.tsinghua.edu.cn/packages/b5/00/d631e67a838026495268c2f6884f3711a15a9a2a96cd244fdaea53b823fb/typing_extensions-4.14.1-py3-none-any.whl (43 kB) Collecting greenlet>=1 Downloading https://pypi.tuna.tsinghua.edu.cn/packages/d6/6f/b60b0291d9623c496638c582297ead61f43c4b72eef5e9c926ef4565ec13/greenlet-3.2.4-cp310-cp310-win_amd64.whl (298 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 298.7/298.7 kB ? eta 0:00:00 Collecting certifi>=2017.4.17 Using cached https://pypi.tuna.tsinghua.edu.cn/packages/e5/48/1549795ba7742c948d2ad169c1c8cdbae65bc450d6cd753d124b17c8cd32/certifi-2025.8.3-py3-none-any.whl (161 kB) Collecting charset_normalizer<4,>=2 Using cached https://pypi.tuna.tsinghua.edu.cn/packages/e2/c6/f05db471f81af1fa01839d44ae2a8bfeec8d2a8b4590f16c4e7393afd323/charset_normalizer-3.4.3-cp310-cp310-win_amd64.whl (107 kB) Collecting urllib3<3,>=1.21.1 Using cached https://pypi.tuna.tsinghua.edu.cn/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl (129 kB) Collecting idna<4,>=2.5 Using cached https://pypi.tuna.tsinghua.edu.cn/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl (70 kB) Collecting six Using cached https://pypi.tuna.tsinghua.edu.cn/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl (11 kB) Collecting redis Downloading https://pypi.tuna.tsinghua.edu.cn/packages/e8/02/89e2ed7e85db6c93dfa9e8f691c5087df4e3551ab39081a4d7c6d1f90e05/redis-6.4.0-py3-none-any.whl (279 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 279.8/279.8 kB ? eta 0:00:00 Collecting colorama Using cached https://pypi.tuna.tsinghua.edu.cn/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl (25 kB) Collecting async-timeout>=4.0.3 Downloading https://pypi.tuna.tsinghua.edu.cn/packages/fe/ba/e2081de779ca30d473f21f5b30e0e737c438205440784c7dfc81efc2b029/async_timeout-5.0.1-py3-none-any.whl (6.2 kB) Installing collected packages: urllib3, typing-extensions, six, python-dotenv, psutil, markupsafe, itsdangerous, idna, greenlet, colorama, charset_normalizer, certifi, blinker, async-timeout, werkzeug, sqlalchemy, requests, redis, jinja2, click, flask, flask-sse Successfully installed async-timeout-5.0.1 blinker-1.9.0 certifi-2025.8.3 charset_normalizer-3.4.3 click-8.2.1 colorama-0.4.6 flask-3.1.2 flask-sse-1.0.0 greenlet-3.2.4 idna-3.10 itsdangerous-2.2.0 jinja2-3.1.6 markupsafe-3.0.2 psutil-7.0.0 python-dotenv-1.1.1 redis-6.4.0 requests-2.32.5 six-1.17.0 sqlalchemy-2.0.43 typing-extensions-4.14.1 urllib3-2.5.0 werkzeug-3.1.3 [notice] A new release of pip available: 22.3.1 -> 25.2 [notice] To update, run: python.exe -m pip install --upgrade pip (clean_env) PS C:\Users\Administrator\Desktop> (clean_env) PS C:\Users\Administrator\Desktop> # 运行Python脚本 (clean_env) PS C:\Users\Administrator\Desktop> python "E:\verify_path.py" E:\Python310\python.exe: can't open file 'E:\\verify_path.py': [Errno 2] No such file or directory (clean_env) PS C:\Users\Administrator\Desktop> (clean_env) PS C:\Users\Administrator\Desktop> # 停用虚拟环境 (clean_env) PS C:\Users\Administrator\Desktop> deactivate PS C:\Users\Administrator\Desktop> # 保存为 E:\Setup-PowerShell7.ps1 PS C:\Users\Administrator\Desktop> param( >> [switch]$Install, >> [switch]$Configure >> ) PS C:\Users\Administrator\Desktop> PS C:\Users\Administrator\Desktop> # 安装 PowerShell 7 PS C:\Users\Administrator\Desktop> if ($Install) { >> $url = "https://github.com/PowerShell/PowerShell/releases/download/v7.3.6/PowerShell-7.3.6-win-x64.msi" >> $output = "$env:TEMP\PowerShell-7.3.6-win-x64.msi" >> >> Invoke-WebRequest -Uri $url -OutFile $output >> Start-Process msiexec.exe -ArgumentList "/i `"$output`" /qn" -Wait >> Remove-Item $output -Force >> } PS C:\Users\Administrator\Desktop> PS C:\Users\Administrator\Desktop> # 配置环境 PS C:\Users\Administrator\Desktop> if ($Configure) { >> # 创建配置文件 >> $pwshProfile = "$env:USERPROFILE\Documents\PowerShell\Microsoft.PowerShell_profile.ps1" >> @' >> # 配置文件内容 >> '@ | Set-Content -Path $pwshProfile -Encoding UTF8 >> >> # 创建脚本文件 >> # ... >> >> # 创建快捷方式 >> # ... >> >> Write-Host "PowerShell 7 环境配置完成!" -ForegroundColor Green >> Write-Host "请使用桌面上的 'PowerShell 7' 快捷方式启动" -ForegroundColor Yellow >> } PS C:\Users\Administrator\Desktop> PS C:\Users\Administrator\Desktop> # 使用示例: PS C:\Users\Administrator\Desktop> # .\Setup-PowerShell7.ps1 -Install -Configure PS C:\Users\Administrator\Desktop> .\Setup-PowerShell7.ps1 -Install -Configure .\Setup-PowerShell7.ps1 : 无法将“.\Setup-PowerShell7.ps1”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。 所在位置 行:1 字符: 1 + .\Setup-PowerShell7.ps1 -Install -Configure + ~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (.\Setup-PowerShell7.ps1:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException PS C:\Users\Administrator\Desktop> da # 运行桌面分析 da : 无法将“da”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。 所在位置 行:1 字符: 1 + da # 运行桌面分析 + ~~ + CategoryInfo : ObjectNotFound: (da:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException PS C:\Users\Administrator\Desktop> ve # 运行环境验证 ve : 无法将“ve”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。 所在位置 行:1 字符: 1 + ve # 运行环境验证 + ~~ + CategoryInfo : ObjectNotFound: (ve:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException PS C:\Users\Administrator\Desktop> clean # 清理桌面 clean : 无法将“clean”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。 所在位置 行:1 字符: 1 + clean # 清理桌面 + ~~~~~ + CategoryInfo : ObjectNotFound: (clean:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException PS C:\Users\Administrator\Desktop> # 创建并激活环境 PS C:\Users\Administrator\Desktop> python -m venv "E:\myenv" PS C:\Users\Administrator\Desktop> . "E:\myenv\Scripts\Activate.ps1" (myenv) PS C:\Users\Administrator\Desktop> (myenv) PS C:\Users\Administrator\Desktop> # 在虚拟环境中工作 (myenv) PS C:\Users\Administrator\Desktop> pip install pandas Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple Collecting pandas Downloading https://pypi.tuna.tsinghua.edu.cn/packages/d8/df/5ab92fcd76455a632b3db34a746e1074d432c0cdbbd28d7cd1daba46a75d/pandas-2.3.2-cp310-cp310-win_amd64.whl (11.3 MB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 11.3/11.3 MB 81.8 MB/s eta 0:00:00 Collecting numpy>=1.22.4 Using cached https://pypi.tuna.tsinghua.edu.cn/packages/a3/dd/4b822569d6b96c39d1215dbae0582fd99954dcbcf0c1a13c61783feaca3f/numpy-2.2.6-cp310-cp310-win_amd64.whl (12.9 MB) Collecting pytz>=2020.1 Using cached https://pypi.tuna.tsinghua.edu.cn/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl (509 kB) Collecting tzdata>=2022.7 Using cached https://pypi.tuna.tsinghua.edu.cn/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl (347 kB) Collecting python-dateutil>=2.8.2 Using cached https://pypi.tuna.tsinghua.edu.cn/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl (229 kB) Collecting six>=1.5 Using cached https://pypi.tuna.tsinghua.edu.cn/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl (11 kB) Installing collected packages: pytz, tzdata, six, numpy, python-dateutil, pandas Successfully installed numpy-2.2.6 pandas-2.3.2 python-dateutil-2.9.0.post0 pytz-2025.2 six-1.17.0 tzdata-2025.2 [notice] A new release of pip available: 22.3.1 -> 25.2 [notice] To update, run: python.exe -m pip install --upgrade pip (myenv) PS C:\Users\Administrator\Desktop> python myscript.py E:\Python310\python.exe: can't open file 'C:\\Users\\Administrator\\Desktop\\myscript.py': [Errno 2] No such file or directory (myenv) PS C:\Users\Administrator\Desktop> (myenv) PS C:\Users\Administrator\Desktop> # 退出环境 (myenv) PS C:\Users\Administrator\Desktop> deactivate PS C:\Users\Administrator\Desktop> Set-ExecutionPolicy RemoteSigned -Scope CurrentUser PS C:\Users\Administrator\Desktop> Set-ExecutionPolicy RemoteSigned -Scope CurrentUser PS C:\Users\Administrator\Desktop> $scriptPath = Join-Path $PSScriptRoot "myscript.ps1" Join-Path : 无法将参数绑定到参数“Path”,因为该参数为空字符串。 所在位置 行:1 字符: 25 + $scriptPath = Join-Path $PSScriptRoot "myscript.ps1" + ~~~~~~~~~~~~~ + CategoryInfo : InvalidData: (:) [Join-Path],ParameterBindingValidationException + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Microsoft.PowerShell.Commands.Join PathCommand PS C:\Users\Administrator\Desktop>
08-24
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值