有趣的赋值,了解一下

python 随笔

业余 python 爱好者又上线了,离上次发博过去几个月了,真的是懒!
期间完成了一段目前为止最完整、效果良好、800 多行的小游戏代码,由于运维工作忙,抽时间再将其详尽的分享出来。
此次更博,是想把之前的笔记在此做一个简略的记录,还是因为懒。

笔记内容

  1. 不是想象中的赋值
  2. 生成器 与 列表生成式

  1. 不是想象中的赋值
    废话少说,先看代码
# 请看第一段代码
def fibs(n=10):
    a, b = 0, 1
    result = []
    for i in range(n):
        a, b = b, a+b
        result.append(a)
    return result
# 直接调用,验看结果
fibs()
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]  # 结果
# 再看第二段代码
def fibs(n=10):
    a, b = 0, 1
    result = []
    for i in range(n):
        a = b
        b = a + b
        result.append(a)
    return result
# 直接调用,验看结果
fibs()
[1, 2, 4, 8, 16, 32, 64, 128, 256, 512] # 结果

原来我以为 python 迭代的那种赋值方式是为了便捷、美观,看来是和惯性思维是有出入的。

a, b = b, a+b

这种方式是先计算完 “=” 右边的值,再赋给左边的参数,比如这里 a = 0 b = 1 a+b=1 ,赋值后 a = 1 b = 1,所以第一段函数出现正确的斐波那契数列。

a = b
b = a + b

这更简单,其实就是 b 反复和自己相加,最后赋值给 a .不明白自己原来为什么以为这两种赋值方式是一样的,傻~

2 生成器 generator 与 列表生成式
列表生成式对于 Python 患者应该很熟悉了,简约大方又聪明。

[demo ** 2 for demo in range(1, 10) if demo % 2 == 0]
求 10 以内的偶数的平方
[4, 16, 36, 64]

生成器 (generator),引自廖雪峰 Python 生成器 的描述,它可以和列表生成式一样,用一个简单的带 “()” 的式子生成,然后用 next() 来取值,直到超出索引范围,抛出一个停止迭代的报错 StopIteration。

temp = (x ** x for x in range(1, 5))
temp 保存的是个算法,如下:
temp
<generator object <genexpr> at 0x0000000005616AF0>
next(temp)
1
4
27
256
Boom……(此时炸了,不复制了)

另一个重要的语句 yield,常会用这个工具制作生成器。yield 的作用就是把一个函数变成一个 generator,调用函数时返回的是一个可迭代的对象。生成器用 for 循环进行遍历,不会抛出异常。

小记

断断续续学了这么久,还是能看到好多新鲜的知识点,应该保持一个学习并记录的习惯!

<think>嗯,用户这次的问题聚焦在Android系统源码中DisplayFrames.mSystem的赋值逻辑上。从用户引用的代码片段来看,ta应该正在分析WindowManagerService相关的模块,特别是窗口尺寸计算部分。用户能精准定位到DisplayFrames这个核心类,说明对Android窗口管理系统有相当程度的了解。注意到用户前一个问题涉及DisplayFrames中多个frame的赋值方式,这次专门追问mSystem这个特殊字段。有趣的是mSystem的语义和其他frame不同——它代表系统窗口专用区域而非普通应用窗口区域。用户可能正在研究状态栏/导航栏等系统窗口的布局逻辑,或是遇到系统窗口尺寸异常的问题。从技术角度看,mSystem的赋值需要重点关注两个环节:首先是DisplayPolicy.computeSystemDecorInsets()这个关键算法,这里会考虑刘海屏、圆角等物理特性计算安全区域;其次是DisplayFrames构造函数中依赖DisplayInfo的系统参数。用户提供的引用[1]提到mStableFrame等字段的赋值,其实和mSystem是同级概念,这提示ta需要横向对比其他frame的初始化逻辑。考虑到系统窗口的特殊性,在回答时需要强调PhoneWindowManager的介入点。比如系统主题切换或屏幕旋转时,DisplayPolicy会重新计算装饰边距(DecorInsets),这直接影响mSystem的值。用户若是开发者,可能需要overridecomputeSystemDecorInsets()实现定制布局;若是逆向分析,则需注意厂商自定义的DisplayPolicy子类。需要提醒用户的是,Android11之后mSystem的计算加入了手势导航等新变量。若用户参考的代码版本较旧,最好注明版本差异。另外DisplayFrames源码里藏了不少tricky的边界处理,比如对传感器孔洞区域的二次修正,用户若遇到边缘case可以具体讨论。</think> 在 Android 源码中,`DisplayFrames.mSystem` 的初始化及赋值主要通过以下方式实现,核心逻辑位于 **窗口管理系统(WMS)** 和 **DisplayPolicy** 相关类中: --- ### **1. 初始化位置** `mSystem` 在 `DisplayFrames` 构造函数中被初始化,其值**依赖于系统装饰边距(System Decor Insets)**: ```java // 文件: frameworks/base/services/core/java/com/android/server/wm/DisplayFrames.java public class DisplayFrames { public final Rect mSystem = new Rect(); public DisplayFrames(int displayId, DisplayInfo info, Rect initialBounds) { // 通过系统边距计算初始区域 mSystem.set(initialBounds); if (info != null) { // 从 DisplayInfo 获取系统装饰边距并应用 mSystem.inset(info.decorInsets.left, info.decorInsets.top, info.decorInsets.right, info.decorInsets.bottom); } } } ``` --- ### **2. 动态赋值流程** `mSystem` 的具体值由 **`DisplayPolicy`** 计算得出: #### **(1) `DisplayPolicy.computeSystemDecorInsets()`** ```java // 文件: frameworks/base/services/core/java/com/android/server/wm/DisplayPolicy.java public void computeSystemDecorInsets(DisplayFrames displayFrames, DisplayInfo displayInfo) { // 1. 获取状态栏/导航栏等系统UI高度 final int statusBarHeight = getStatusBarHeight(); final int navBarHeight = getNavigationBarHeight(); // 2. 根据屏幕方向计算系统装饰边距 switch (displayInfo.rotation) { case ROTATION_90: decorInsets.set(0, 0, statusBarHeight, navBarHeight); break; case ROTATION_270: decorInsets.set(statusBarHeight, navBarHeight, 0, 0); break; default: decorInsets.set(0, statusBarHeight, navBarHeight, 0); } // 3. 将计算结果同步到 DisplayInfo displayInfo.decorInsets = decorInsets; } ``` #### **(2) `DisplayFrames.update()` 调用** 在窗口布局过程中,`DisplayPolicy` 计算的 `decorInsets` 被应用到 `DisplayFrames.mSystem`: ```java // 文件: frameworks/base/services/core/java/com/android/server/wm/DisplayFrames.java public void update(DisplayInfo info, Rect initialBounds) { // 更新系统区域:应用最新的装饰边距 mSystem.set(initialBounds); mSystem.inset(info.decorInsets.left, info.decorInsets.top, info.decorInsets.right, info.decorInsets.bottom); } ``` --- ### **关键调用栈** 1. **`WindowManagerService#resize()`** 触发窗口尺寸更新时,调用 `DisplayPolicy` 计算新边距。 2. **`DisplayPolicy#layoutWindowLw()`** 为每个窗口布局时使用 `DisplayFrames.mSystem` 避开系统保留区域(如状态栏)[^3]。 3. **`DisplayInfo` 更新** WMS 通过 `DisplayInfo` 传递屏幕物理属性(如旋转方向、刘海区域)以重新计算 `decorInsets`[^2]。 --- ### **技术总结** - **初始值来源**:`DisplayFrames` 构造函数基于 `DisplayInfo.decorInsets` 设定 `mSystem`。 - **动态更新**: `DisplayPolicy` 根据屏幕旋转、系统UI尺寸实时计算 `decorInsets` → 更新 `DisplayInfo` → 触发 `DisplayFrames.update()` 重设 `mSystem`。 - **作用**: 确保应用窗口不会覆盖系统保留区域(如状态栏),保持系统UI可见性[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值