TouchDesigner 中使用 Python 的打印(print)基础
针对初学者介绍了在 TouchDesigner 文本端口(Textport)中使用 Python 打印输出的核心概念与常见操作。文档以示例代码与概念解释相结合,便于教学使用。
1. 打开 Textport 并运行脚本
在 TouchDesigner 界面,通过右上角的下拉菜单打开 Textport。在 Textport 中输入脚本,右键点击并选择 Run Script 执行,输出将显示在 Textport 窗口中。
2. 基本的 print()
用法
# 单引号与双引号等价,但必须配对
print('hello world')
print("hello world")
- 功能:在控制台输出字符串。
- 注意:引号必须匹配,否则会报语法错误。
3. 数据类型与打印
Python 中常见的数据类型及打印方式:
# 字符串(string)
print("这是一个字符串")
# 整数(integer)
print(42)
# 浮点数(float)
print(3.14)
# 布尔值(boolean)
print(True)
print(False)
- 字符串:一系列字母、数字和符号,需用引号包裹。
- 整数:不带小数点的数字。
- 浮点数:包含小数点的数字。
- 布尔值:
True
或False
,在数学运算中会自动转换为1
与0
。
4. 变量定义与打印
将数据赋给变量后再打印:
text = "TouchDesigner"
print(text)
num = 2
print(num * 2) # 整数相乘,输出 4
flt = 2.5
print(flt * 2) # 浮点数相乘,输出 5.0
flag = False
print(flag) # 输出 False
print(flag * 2) # False 在运算中等同于 0,输出 0
- 变量:通过
变量名 = 值
声明。 - 操作:数值类型可参与算术运算;字符串相加实现拼接。
5. 多行字符串与输出换行
5.1 使用转义字符 \n
print("第一行\n第二行\n第三行")
\n
表示换行符。
5.2 三引号定义多行字符串
text = """第一行
第二行
第三行"""
print(text)
- 三引号(
'''
或"""
)可定义跨多行的字符串,便于阅读和维护。
6. 字符串格式化与占位符
6.1 基础占位符 %s
, %d
, %r
template = "你好,%s!今天有 %d 只猫。"
name = "Alice"
count = 3
print(template % (name, count))
%s
:字符串占位;%d
:整数占位;%r
:任意类型的原始表示。
6.2 传入多个参数
text = "您有 %s 猫,颜色是 %s,体重 %.1f kg。"
print(text % ("两只", "黑色", 4.5))
- 参数需按顺序放入元组,类型需与占位符对应或使用
%r
。
7. 数值与字符串混合打印
7.1 使用逗号分隔
name = "Count"
value = 10
print(name, value) # 输出:Count 10,中间自动添加空格,且不计算运算
7.2 显式转换
print("Count is " + str(value)) # 将整数转为字符串后拼接
8. 常见调试场景
- 检查变量值:在脚本中多处插入
print(var)
,快速了解运行状态。 - 运行顺序:Python 按照脚本从上至下执行,先定义变量再使用。
- 数据类型误用:布尔、数值与字符串混用时需注意自动转换与报错情况。
9. 小结
print()
是最简单有效的调试工具,能实时在 Textport 查看变量与执行结果。- 掌握不同数据类型的打印方式、格式化占位符和多行字符串定义,能够编写清晰易读的脚本。
- 在 TouchDesigner 中结合 Python 脚本,可实现丰富的可视化与数据处理任务。
^1
⁂
TouchDesigner 中使用 Python 的变量(Variables)详解
1. 变量的定义与概念
变量(Variable) 是用于存储和重用数据的“容器”,可随时取回并参与运算或引用。
# 定义整数类型变量
red_marbles = 10 # 红色弹珠数量
blue_marbles = 5 # 蓝色弹珠数量
green_cat_eyes= 6 # 绿“猫眼”弹珠数量
blue_cat_eyes = 12 # 蓝“猫眼”弹珠数量
- 等号左侧为 变量名,右侧为 值。
- 变量名应具可读性、避免空格及特殊字符。
2. 变量运算与求和
将各类弹珠总数累加为总库存:
total_marbles = red_marbles + blue_marbles + green_cat_eyes + blue_cat_eyes
- 不同数值变量可直接相加,结果赋予新变量
total_marbles
。
3. 打印带占位符的字符串
在打印时使用 %d
、%s
等占位符,将变量嵌入文本中:
# 模板字符串中,%d 表示整数占位
template = "库存:红色 %d,蓝色 %d,绿猫眼 %d,蓝猫眼 %d,总计 %d"
print(template % (red_marbles, blue_marbles, green_cat_eyes, blue_cat_eyes, total_marbles))
%
后跟元组,顺序对应所有占位符。- 可追加分隔线,增强可读性:
print("-" * 40) # 输出 40 个连字符
4. 从 Table DAT 读取变量
在 TouchDesigner 中,弹珠数量也可存储于 Table DAT 单元格,通过 Python 引用:
# 假设已有名为 table_marbles 的 Table DAT,4 行 2 列
# 单元格格式:第一列为名称,第二列为数量
red_marbles = op('table_marbles')[0, 1] # 第一行、第二列
blue_marbles = op('table_marbles')[1, 1]
green_cat_eyes = op('table_marbles')[2, 1]
blue_cat_eyes = op('table_marbles')[3, 1]
op('table_marbles')
获取 Table DAT 操作符引用。[row, col]
指定行列索引(从 0 开始)。
5. 操作节点参数的变量引用
可将常用操作符(Operator)与其参数通过变量简化多次调用:
# 引用名为 level1 的 Level TOP
lvl = op('level1')
# 直接修改参数
lvl.par.opacity = 0.0
lvl.par.invert = 0.31
lvl.par.blacklevel = 0.27
# …以此类推
op('level1')
获取节点,保存在变量lvl
中;.par.参数名
访问并修改对应参数。
6. 批量修改参数的优化
对于多个参数的连续修改,可先将节点引用存入变量,再依次调用,减少重复 op()
:
lvl = op('level1') # 只调用一次 op()
lvl.par.opacity = 0.78
lvl.par.invert = 0.31
lvl.par.blacklevel = 0.27
lvl.par.brightness1 = 1.45
lvl.par.gamma1 = 0.50
lvl.par.contrast = 1.76
- 变量复用提高脚本简洁性与可维护性。
7. 结合 Table DAT 批量应用预设
假设有一个名为 presets
的 Table DAT,包含多行预设参数,可动态读取并赋值:
preset_table = op('presets') # Table DAT
preset_index = 1 # 当前预设行(从 0 开始)
# 从表头获取参数名称,援引至 Level TOP
lvl = op('level1')
param_names = ['invert', 'blacklevel', 'brightness1', 'gamma1', 'contrast', 'opacity']
for col, pname in enumerate(param_names):
value = preset_table[preset_index, col+1] # 列 +1 跳过名称列
setattr(lvl.par, pname, value) # 动态赋值
preset_index
可由 UI 常数或 CHOP 通道控制,动态切换预设行;setattr(object, name, value)
根据字符串name
设置属性。
8. 结合常数(Constant CHOP)动态切换行号
可使用 Constant CHOP 的输出通道值作为 preset_index
,并将其转换为整数:
# 读取 Constant CHOP 输出
const_chop = op('constant1')
idx_float = const_chop['chan1'].eval() # 通道值(浮点)
preset_index = int(idx_float) # 转为整数
# 按上例循环应用预设
.eval()
获取当前通道数值;int()
将浮点数转整,与行号匹配。
小结
- 变量 用于存储数据与引用节点,简化代码与提升可维护性。
- 占位符格式化 与 字符串拼接 结合变量,便于输出动态信息。
- Table DAT 与 Operator.par 的变量引用,使数据与节点参数互通。
- 将 常数 CHOP 或 UI 控件值转为整数,即可动态切换数据行或预设。
掌握以上模式,便可在 TouchDesigner 中编写结构清晰、复用性高的 Python 脚本,快速对数据与节点进行联动与自动化控制。
^1
⁂
TouchDesigner 中的 Python 引用(References)详解
1. 基本语法:op()
与索引/名称引用
- 引用 Operator
# 通过名称获取 Operator 引用
lfo = op('lfo1')
# 获取该 Operator 的第一个通道(名称引用)
value = lfo[‘chan1’]
# 或通过通道索引(位置引用,0 开始)
value = lfo[^0]
- `op('名称')`:返回指定名称的 Operator。
- `[...]`:方括号内可填通道名称(字符串)或通道索引(整数)。
- 引用 TOP 参数
circle = op('circle1')
# 将 LFO 通道驱动 circle 的 center X
circle.par.centerx = op('lfo1')['chan1']
2. 反向与组合运算
- 取相反值
val = op('lfo1')[^0]
circle.par.centery = -val # 反向移动
- 对角线运动
x = op('lfo1')[^0]
y = op('lfo1')[^0]
circle.par.centerx, circle.par.centery = x, y
3. 利用 CHOP/Constant CHOP 驱动表达式
- Constant CHOP + Speed CHOP
rate_ch = op('constant1')['chan1'] # 固定速率
timer = op('speed1')['chan1']
# speed1 根据 rate_ch 持续累加
- 结合三角函数绘制圆环
import math
r = 0.4
t = op('speed1')[^0]
circle.par.centerx = math.cos(t) * r
circle.par.centery = math.sin(t) * r
- 绘制椭圆
r1 = 0.4; r2 = 0.2
circle.par.centerx = math.cos(t) * r1
circle.par.centery = math.sin(t) * r2
4. 从 Table DAT 中读取参数
tbl = op('table1')
# 2×2 表:行 0→radius1, 行 1→radius2;列 0→名称、列 1→数值
r1 = tbl[0,1]
r2 = tbl[1,1]
[row, col]
指定行列索引。- 也可用表头名称:
tbl['radius1', 1]
。
5. 文件与路径引用示例
- 引用 Samples 目录
import os
path = app.samplesFolder + '/map/planet.f4v'
movie = op('moviefilein1')
movie.par.file = path
- 从 Folder DAT 获取路径
fld = op('folder1')
# 第三行、第二列(列索引 1)路径
movie.par.file = fld[2,1]
6. 阅读 Python Help 文档
- 在 Parameter 界面点击小问号,打开 Class Help。
- 理解 Members(成员)与 Methods(方法):
- TOP 类成员:
width
、height
、aspect
等。 - Operator 类成员:
name
、digits
、cookTime
等。
- TOP 类成员:
- 在 Textport 中测试表达式:
op('moviefilein1').fileHeight # 返回视频高度(像素)
op('moviefilein1').fileWidth # 返回视频宽度(像素)
- 若出现 NameError,表明忘记加引号或变量未定义,需补全字符串或变量声明。
小结
- 使用
op('name')
获取 Operator 引用,并通过索引或名称访问其 Channel、DAT、参数等。 - 结合数学模块,可在表达式中绘制圆形、椭圆等复杂运动轨迹。
- 从 Table DAT、Folder DAT 等数据表中动态获取数值与路径。
- 掌握阅读 Python Help 文档,快速查找合适的成员与方法,拓展脚本功能。
通过上述技巧,能够在 TouchDesigner 中编写清晰、动态、可扩展的 Python 表达式,实现复杂的数据联动与可视化控制。
^1
⁂
TouchDesigner 中的 Python 逻辑基础(Logic – Part 1)
概览
在 TouchDesigner 脚本中,逻辑(Logic) 用于根据条件执行不同操作。常见构造包括:
if
、elif
、else
- 比较运算符:
>
、<
、>=
、<=
、==
、!=
- 逻辑运算符:
and
、or
- 取模运算符:
%
以下示例均在 Text DAT 中编辑,配合 外部文本编辑器(如 Sublime)更易编写和调试。
1. 基本的 if…else
语句
# 定义变量
my_int = 5
# 简单打印
print("my_int is %d" % my_int)
# 基本 if…else
if my_int >= 6:
print("This number is greater than or equal to 6")
else:
print("This number is less than 6")
if
后跟条件表达式,末尾须加冒号:
- 条件成立时执行缩进块,否则执行
else
块 pass
可用于空操作,保持语法完整:
if my_int >= 6:
pass # 条件成立时不做任何事
else:
print("Number is less than 6")
2. elif
多分支测试
my_int = 6
if my_int > 6:
print("This number is greater than 6")
elif my_int == 6:
print("This number is exactly 6")
else:
print("This number is less than 6")
elif
(else if)可添加额外条件,避免多层嵌套- 建议每个
if
块都配对else
,确保所有情况均被覆盖
3. 不等于运算:!=
if my_int != 6:
print("This number is not 6")
else:
print("This number is 6")
!=
表示“不等于”,是比较运算符之一
4. 嵌套 if
:测试奇偶
my_int = 8
if my_int >= 6:
print(">=6:", my_int)
# 测试奇偶:用 modulus (%) 判断余数
if my_int % 2 == 0:
print("Even number")
else:
print("Odd number")
else:
print("<6:", my_int)
%
运算符返回除法余数- 若
my_int % 2 == 0
,则为偶数,否则为奇数
5. 同时测试多个条件:and
my_int = 7
# 测试范围:同时检查两端
if my_int > 4 and my_int < 10:
print("%d is between 4 and 10" % my_int)
else:
print("%d is <=4 or >=10" % my_int)
and
要求左右两个条件都为真,整体才为真
6. 同或测试:or
my_int = -5
# 测试大于 4 或等于 -5
if my_int > 4 or my_int == -5:
print("%d is >4 or ==-5" % my_int)
else:
print("%d is <=4 and !=-5" % my_int)
or
任一条件为真即执行分支
7. 用变量降低硬编码
将测试值抽为变量,简化后续修改:
test_val = 4
my_int = 7
if my_int > test_val:
print("%d is greater than %d" % (my_int, test_val))
else:
print("%d is less than or equal to %d" % (my_int, test_val))
- 将常用数字或比较值放在顶部,便于统一管理
小结
if
/elif
/else
:构建分支逻辑- 比较运算符:
>
,<
,>=
,<=
,==
,!=
- 逻辑运算符:
and
,or
- 取模运算:
%
用于判断奇偶或循环余数 - 变量管理:抽象常量,减少硬编码
掌握以上逻辑构造后,可在 TouchDesigner Python 脚本中实现复杂的条件判断与分支控制,为后续网络中的交互和自动化提供强大支持。
^1
⁂
TouchDesigner 中的 Python 逻辑进阶(Logic – Part 2)
在 Part 1 中学习了基本的逻辑分支与比较运算,本章聚焦于在 TouchDesigner 中使用 References(引用)将 CHOP 通道作为对象,动态读取与比较其值,并探索 Channel Class 的成员属性。
1. 从 Constant CHOP 读取通道值
# 假设网络中已有 Constant CHOP:constant1 和 constant2
# 并将其两个通道分别命名为 chan1、chan2
# 将通道值当作浮点数读取
val1 = float(op('constant1')['chan1'].eval())
val2 = float(op('constant1')['chan2'].eval())
val3 = float(op('constant2')['chan1'].eval())
val4 = float(op('constant2')['chan2'].eval())
# 打印以验证
print("val1 =", val1)
print("val2 =", val2)
print("val3 =", val3)
print("val4 =", val4)
op('constant1')['chan1']
返回 Channel 对象.eval()
得到通道当前数值float(...)
转为浮点数,避免%d
只显示整数
2. 比较两个 CHOP 通道
# 定义比较函数,传入两组值及描述
def compare(name1, v1, name2, v2):
if v1 == v2:
print(f"{name1} == {name2}")
elif v1 > v2:
print(f"{name1} > {name2}")
else:
print(f"{name1} < {name2}")
# 调用比较
compare("chan1@const1", val1, "chan1@const2", val3)
compare("chan2@const1", val2, "chan2@const2", val4)
- 三分支判断相等、大于、小于
- 函数封装减少重复代码
3. 利用 Channel Class 读取元信息
Channel 对象拥有丰富成员,可获取索引、名称、所属 Operator 等属性:
ch = op('constant1')['chan1'] # Channel 对象
idx = ch.index # 通道索引(位置)
name = ch.name # 通道名字(字符串)
owner = ch.owner # 所属 Operator 对象
print("Index:", idx)
print("Name :", name)
print("Owner:", owner.path) # 输出 Operator 路径
.index
、.name
、.owner
均为成员属性- 在脚本中可根据需要访问其他成员,如
.vals
、.sampleRate
等
4. 综合示例:基于引用的动态比较
# 读取两组通道
c1 = op('constant1')
c2 = op('constant2')
v1 = c1['chan1'].eval()
v2 = c2['chan1'].eval()
# 获取 Channel 对象,用于读取元信息
ch1 = c1['chan1']
ch2 = c2['chan1']
# 定义带元信息的比较
if v1 == v2:
print(f"{ch1.owner.name}.{ch1.name} == {ch2.owner.name}.{ch2.name}")
elif v1 > v2:
print(f"{ch1.owner.name}.{ch1.name} > {ch2.owner.name}.{ch2.name}")
else:
print(f"{ch1.owner.name}.{ch1.name} < {ch2.owner.name}.{ch2.name}")
- 动态引用 Operator 与通道名称,输出格式如
constant1.chan1 > constant2.chan1
- 更具可读性,网络名称即作文中描述
5. 小结
- 动态引用 CHOP:通过
op(…)[…]
获取 Channel 对象,.eval()
得到值。 - 类型转换:将通道数值转为浮点数,避免整数格式化丢失小数。
- 封装比较:使用函数或分支逻辑组织代码,提升可维护性。
- Channel Class:访问
.index
、.name
、.owner
等属性,获取通道元信息。
掌握以上模式后,便可在 TouchDesigner 中编写更加灵活、动态且易扩展的 Python 脚本,实现控件驱动逻辑、数据监测与自动化控制。
^1
⁂
Python 列表(Lists)基础
TouchDesigner 中可通过 Python 列表管理任意数量和类型的数据。本节介绍列表的定义、索引、切片、动态添加与嵌套用法。
1. 列表概念
# 列表:一系列有序元素,使用方括号 [] 包裹,元素间以逗号分隔
kitties = ['Maddy', 'Reagan', 'Kitty'] # 字符串列表
numbers = [1, 2, 3, 4, 5] # 整数列表
mixed = ['eggs', 3.14, True, 42] # 混合类型列表
- 列表可包含任意类型,甚至嵌套列表
- 列表长度可动态变化
2. 访问单个元素(索引)
grocery = ['eggs', 'milk', 'bread', 'butter', 'coffee']
print(grocery[^0]) # 输出 'eggs',索引从 0 开始
print(grocery[^4]) # 输出 'coffee'
- 索引超出范围会报
IndexError
3. 切片(Slicing)
print(grocery[:3]) # 前 3 个元素 ['eggs','milk','bread']
print(grocery[2:]) # 从索引 2 到末尾 ['bread','butter','coffee']
print(grocery[-2:]) # 最后 2 个元素 ['butter','coffee']
list[start:end]
:包含start
,不含end
- 省略
start
或end
分别表示从头或到尾 - 负索引从末尾开始计算(
-1
表示最后一个元素)
4. 列表长度
print(len(grocery)) # 输出 5
len()
返回元素个数
5. 动态添加元素
lst = [] # 空列表
lst.append('apple') # 在末尾添加单个元素
lst.extend(['kiwi', 10, True]) # 在末尾追加另一个列表所有元素
print(lst) # ['apple','kiwi',10,True]
append(x)
:添加单个元素extend(iterable)
:添加可迭代对象所有元素
6. 嵌套列表(列表的列表)
# 超市部门及库存
store = [
['Fruit', ['apple','kiwi','orange']],
['Baked Goods', ['bread','pie','muffin']],
['Drinks', ['cola','sprite','root beer']],
]
# 访问“Fruit”部门列表
print(store[^0]) # ['Fruit',['apple',...]]
print(store[^0][^0]) # 'Fruit' # 部门名称
print(store[^0][^1]) # ['apple','kiwi','orange'] # 库存列表
# 访问“Fruit”库存第 2 项
print(store[^0][^1][^1]) # 'kiwi'
store[行][列]
对应二维坐标- 可随层级继续嵌套(不建议过深)
7. 小结
- 定义:
lst = [a, b, c]
- 索引:
lst[i]
获取单个元素 - 切片:
lst[start:end]
批量获取子序列 - 长度:
len(lst)
- 添加:
append()
与extend()
- 嵌套:
lst = [[...],[...]]
用方括号实现多层列表
掌握以上操作,即可在 TouchDesigner 脚本中灵活管理多种数据集。
⁂
TouchDesigner 中的 Python 列表进阶应用
本节示例演示如何将 TouchDesigner 的 CHOP、SOP 和 COMP 元素视作 Python 列表,利用列表操作简化数据读取与批量控制。
1. 将 Noise CHOP 通道当作列表
# 引用 Noise CHOP,采样点数设为 10
noise1 = op('noise1')
# 读取所有样本为列表
samples = noise1['chan1'].vals # .vals 返回 Python 列表
print("Samples:", samples)
print("First sample:", samples[^0])
print("Number of samples:", noise1.numSamples) # 等价于 len(samples)
.vals
属性提供通道值列表.numSamples
直接返回样本数,无需使用len()
2. 将 SOP 的点(Points)当作列表
# 引用 Rectangle SOP
rect = op('rectangle1')
# Points 属性为 Point 对象列表
pts = rect.points
# 访问第一个 Point
p0 = pts[^0]
print("Point 0:", p0)
# 读取该 Point 的位置坐标
pos = p0.P # [.P] 返回三元组坐标 (x,y,z)
print("Position:", pos)
comp.points
返回Point
对象列表- 可使用索引与切片操作遍历或提取子集
3. 利用 COMP.findChildren() 返回子组件列表
# 引用 Container COMP,其中包含若干 Button COMP
ctr = op('container1')
# 查找深度为 1 且类型为 'button' 的子 OP
buttons = ctr.findChildren(type=buttonCOMP, depth=1)
# 输出所有按钮的名字
for b in buttons:
print("Found button:", b.name)
# 激活第一个按钮(模拟点击)
buttons[^0].click()
findChildren(type=…, depth=…)
返回符合条件的 Operator 列表- 对该列表可进行索引、循环、方法调用(如
.click()
)
4. 列表与脚本交互示例
# 以 Noise CHOP 样本为驱动,改变多个 Rectangle 的位置
noise = op('noise1')['chan1'].vals
rects = op('geo1').findChildren(type=rectangleCOMP, depth=1)
# 保证样本数 >= 矩形数
count = min(len(noise), len(rects))
for i in range(count):
# 使用样本值平移每个矩形的 Y 坐标
rects[i].par.ty = noise[i]
- 将 CHOP 列表与 COMP 子列表一一映射
- 通过循环结合列表索引,批量修改节点参数
小结
.vals
、.points
、.findChildren()
等成员返回 Python 列表或类似列表的集合。- 利用列表索引、切片、迭代,可灵活访问、过滤与批量处理 OP、CHOP、SOP 数据。
- 掌握列表概念后,结合循环与条件判断,可在 TouchDesigner 中实现强大自动化与交互逻辑。
^1
⁂
Python 字典(Dictionaries)基础
在 TouchDesigner 中,字典是一种以 键–值(key–value)对存储数据的结构,适用于按名称快速查找。相比列表按索引访问,字典可直接通过键获取对应值,更加直观。
1. 字典定义与语法
# 定义一个简单字典:键和值均为字符串或数字等
grocery = {
'eggs' : 12, # 键 'eggs' 对应值 12(打)
'milk' : 1.0, # 键 'milk' 对应值 1.0(夸脱)
'butter': 1, # 键 'butter' 对应值 1(磅)
'coffee': 2 # 键 'coffee' 对应值 2(磅)
}
- 使用 大括号
{}
定义字典 - 每个条目为
键:值
,条目间以逗号分隔 - 键(key)通常为字符串,值(value)可为任意类型
2. 通过键访问值
# 读取单项库存
print("Eggs :", grocery['eggs']) # 输出 12
print("Coffee :", grocery['coffee']) # 输出 2
- 访问不存在的键将引发
KeyError
3. 遍历所有键、值或键–值对
# 遍历所有键
for item in grocery.keys():
print("Item:", item)
# 遍历所有值
for qty in grocery.values():
print("Qty :", qty)
# 遍历键–值对
for item, qty in grocery.items():
print(f"{item} -> {qty}")
.keys()
、.values()
、.items()
返回视图对象,可用于循环
4. 动态添加与更新
inv = {} # 空字典
# 添加或更新条目
inv['apple'] = {'qty':12, 'origin':'VT', 'organic':True}
inv['orange'] = {'qty':10, 'origin':'CA', 'organic':False}
# 修改已存在键对应值
inv['apple']['qty'] = 8
- 直接通过
dict[key] = value
添加或更新 - 值可嵌套列表或其他字典
5. 嵌套字典示例
# 多级字典:库存信息
inventory = {
'apple': {'qty':12, 'origin':'VT', 'organic':True},
'orange': {'qty':10, 'origin':'FL', 'organic':False},
'grapes': {'qty':50, 'origin':'CA', 'organic':True}
}
# 访问“apple”库存的所有字段
apple_info = inventory['apple']
print("Apple Info:", apple_info)
# 读取单个字段
print("Apple Qty :", inventory['apple']['qty'])
print("Apple Origin:", inventory['apple']['origin'])
print("Apple Organic:", inventory['apple']['organic'])
- 字典值可为其他字典,实现多级数据结构
6. 格式化输出示例
for item, info in inventory.items():
print(f"{item.title()}: {info['qty']} units from {info['origin']}, organic={info['organic']}")
- 使用 Python 3 的 f-string 插入字典值
.title()
使键名首字母大写
小结
- 字典通过 键 快速定位对应 值,适合无序数据存取。
- 使用
.keys()
、.values()
、.items()
可遍历字典内容。 - 支持动态添加、更新与嵌套,实现灵活数据组织。
- 在 TouchDesigner 脚本中,可用以管理多维参数、组件属性及自定义数据。
^1
⁂
TouchDesigner 中使用 字典(Dictionaries)管理预设
在 TouchDesigner 中,可利用 Python 字典将 UI 组件或节点参数的预设保存为“键–值”映射,通过脚本快速应用、切换多种配置。
1. 准备环境
- 在网络中放置一个 Text DAT(脚本容器)和一个或多个带大量参数的 OP(如 Text TOP、Level TOP)。
- 确保 Text DAT 编辑器已切换至外部编辑器(如 Sublime),便于多行缩进与对齐。
2. 定义“预设字典”
# 保存 Text TOP 多参数预设
text_presets = {
'preset1': { # 预设 1
'text' : 'Hello',
'fontsize' : 20,
'alignx' : 1, # 1=center
'aligny' : 1,
'fontcolorr': 1.0, # 红色通道
'fontcolorg': 0.0,
'fontcolorb': 0.0,
'fontalpha' : 1.0,
'bgcolorr' : 0.0,
'bgcolorg' : 0.0,
'bgcolorb' : 0.0,
'bgalpha' : 0.5,
},
'preset2': { # 预设 2
'text' : 'Monkey',
'fontsize' : 15,
'alignx' : 0, # 0=left
'aligny' : 1,
'fontcolorr': 0.0,
'fontcolorg': 1.0,
'fontcolorb': 0.0,
'fontalpha' : 0.8,
'bgcolorr' : 0.0,
'bgcolorg' : 0.0,
'bgcolorb' : 0.0,
'bgalpha' : 1.0,
}
}
- 键:预设名称(
preset1
、preset2
) - 值:另一个字典,保存对应 OP 各参数的 键–值 对
3. 应用预设
# 目标 Text TOP
txt = op('text1')
# 选定要应用的预设
preset_key = 'preset1' # 可动态修改
# 获取对应参数字典
cfg = text_presets[preset_key]
# 遍历字典,按键调用 OP.par.<参数名>
for key, val in cfg.items():
setattr(txt.par, key, val)
text_presets[preset_key]
返回所选预设的参数字典setattr(txt.par, key, val)
动态赋值,等同于txt.par.text = 'Hello'
等
4. 扩展:多个 OP 与多级字典
可将多种 OP 预设整合在同一字典中,或对单一 OP 的更多层级结构:
# 全局预设字典,包含多个 COMP
presets = {
'preset1': {
'text1': { 'text':'Hi','fontsize':12 },
'level1': { 'brightness1':1.2, 'opacity':0.8 }
},
'preset2': {
'text1': { 'text':'Welcome','fontsize':18 },
'level1': { 'brightness1':0.5, 'opacity':1.0 }
}
}
# 应用
key = 'preset2'
for compName, cfg in presets[key].items():
comp = op(compName)
for param, val in cfg.items():
setattr(comp.par, param, val)
- 外层字典按预设分组,内层字典分 OP,最内层字典分参数
- 双重循环批量设置多个节点的多个参数
小结
- 将多个参数分组存储于字典,可灵活管理多套预设。
- 通过脚本动态选择键并遍历赋值,实现一行代码切换所有配置。
- 嵌套字典支持多节点、多参数的批量控制,为 TouchDesigner 自动化与交互提供强大支持。
^1
⁂
TouchDesigner 中的 Python 函数(Functions)入门
1. 函数概念
- 函数:一段可重复调用的代码块,用于执行单一功能,提高模块化与复用性。
- 语法结构:
def 函数名(参数列表):
"""可选文档注释(docstring)"""
函数体
return 返回值
2. 定义与调用
# 定义函数
def say_hello():
print("Hello, TouchDesigner!") # 在函数内部打印
return # 可省略
# 调用函数
say_hello() # 输出 "Hello, TouchDesigner!"
def
开头,后跟函数名与空括号- 冒号
:
表示函数体开始,体内需缩进 - 调用时写
函数名()
即可执行
3. 返回值(return)
# 返回字符串
def get_greeting():
text = "Hello, World!"
return text # 返回 text
# 调用并接收
g = get_greeting()
print(g) # 输出 "Hello, World!"
return
将值传出函数,调用处才能获取- 不使用
print
,可在外部决定如何显示或处理返回值
4. 带参数的函数
# 将整数转换为小数
def to_decimal(val):
return val / 100.0
# 调用并打印结果
print(to_decimal(40)) # 输出 0.4
- 括号内定义参数名,如
val
- 调用时传入对应实参,如
to_decimal(40)
5. 多参数与多返回值
# 计算小费与账单总额
def tip_calculator(total, tip_pct):
tip = total * tip_pct / 100
bill = total + tip
return tip, bill # 返回元组
# 调用并接收两个返回值
t, b = tip_calculator(50, 15)
print("Tip:", t) # 7.5
print("Bill:", b) # 57.5
- 支持多个参数:
def f(a, b):
return x, y
返回多个值,接收时用元组解包
6. 将函数组合与分离职责
# 计算并返回 (tip, bill)
def calc_tip(total, pct):
tip = total * pct / 100
bill = total + tip
return tip, bill
# 美化输出
def display_bill(data):
tip, bill = data
line = "-" * 30
print(line)
print(f"Tip : {tip:.2f}")
print(f"Total: {bill:.2f}")
print(line)
# 主流程
result = calc_tip(100, 20)
display_bill(result)
calc_tip
专注计算display_bill
专注格式化输出- 职责分离,提高可维护性与复用性
小结
- 使用
def
定义函数,函数体需缩进。 return
将值返回,调用处可捕获。- 参数与返回值支持多元化,满足各种计算需求。
- 通过拆分函数,组合功能块,实现清晰、模块化的脚本结构。
掌握函数后,即可轻松应对 TouchDesigner 中的 CHOP/DAT/COMP execute
回调,将逻辑封装为可复用单元,构建高效自动化流程。
^1
⁂
暂无评论内容