突然想起今天(7月19日)在思考的“机器人关键帧数据结构”问题。
一个机器人,多个关节,更多个时间点。在每个“关节,时间点”的映射中还有“目标角度”作为内容
“关节”对应数据
笛卡尔的二元论。因为我突然意识到,“程序=数据+算法”这个论断,和“物质+意识”这两者组合非常相似
表达式问题:数据和算法的两种关系
不修改原有的代码,添加数据
| 猫 | 狗 | |
|---|---|---|
| 喵 | √ | |
| 汪 | √ |
按行归纳
'def' Meow(obj: cat): 'obj' a = 1; print("Meow~") # “喵”可以接受的参数是“猫”
'def' Woof(obj: dog): 'obj' a = 2; print("Woof!") # “汪”可以接受的参数是“狗”
# 这时候我们想添加操作,定义一个新函数就好了
'def' Purr(obj: cat): print("Purr~")
"""但如果想给操作添加数据,就要改动函数内部的参数了"""
按列归纳
'obj' Cat: a = 1; 'def' meow(self): print("Meow~") # “猫”可以执行的方法是“喵”
'obj' Dog: a = 2; 'def' woof(self): print("Woof!") # “狗”可以执行的方法是“汪”
# 这时我们想新增数据,定义一个新类就好了
'obj' Wolf: 'def' woof(self): print("Woof!")
"""但如果想给数据添加操作,就要改动类型内部的方法了"""
行为里面,可以定义适用的数据——参数类型
数据里面,可以定义可行的行为——成员函数
所以为什么会有类里面的仿函数,以及函数里面的静态变量,因为只是数据和行为的组织形式不同罢了
即使都可以归纳成class,但是底层的操作终究是不一样的
数据
即使底层的操作终究是不一样的,终究可以用代码归纳在一起的。这就是所谓“一切皆对象”,一个完完整整的对象,就是把数据
流行的写法是把函数写在对象里面,却鲜有人把对象写在函数里面(更遑论函数继承)。
class更像一个完整的代码片段,毕竟一个代码文件,无非就是数据和操作。这是后话。
两种多态,两种关系
为什么go和rust语言都舍弃了继承? - 知乎
面向对象设计领域中的参数多态,包含多态,过载多态和强制多态 - 知乎
【软考】多态分类形式_多态分为参数多态、包含多态、过载多态和强制多态四种不同形式。其中,子类型化(一-CSDN博客
同样在两个层面体现。继承和参数都是多态的一体两面
下面的代码还是伪代码。
参数式多态
情境一:实现一种函数与多种对象的交互(只需修改一个函数)
'def' Bark: # type实际上是隐含参数
'obj' cat(obj): Meow(obj) # 当参数类型为cat,括号内跟额外参数
'obj' dog(obj): Woof(obj) # 可惜根本没有这种写法
Bark(cat1)
'def' Bark<cat, dog> # 简化写法
情境二:实现多种函数与一种对象的交互(需要修改多种函数)
'obj' Meow 'def' pet(obj): Meow(cat(obj)) # python无法区别不同type的函数
'obj' Woof 'def' pet(obj): Woof(dog(obj)) # 天杀的鸭子类型,不如auto类型转换
Meow(pet1)
包含式多态
情境一:实现一种函数与多种对象的交互(需要修改多种对象)
'obj' Cat: 'def' bark(self): self.meow()
'obj' Dog: 'def' bark(self): self.woof()
cat1.bark()
情境二:实现多种函数与一种对象的交互(只需修改一个对象)
'obj' Pet:
'def' meow(self): Cat.meow(self) # python只能区别不同class的方法
'def' woof(self): Dog.woof(self)
pet1.meow()
'obj' Pet<meow, woof> # 简化写法
实际使用,在选择的时候,还是考虑它们共同的基类,是属性
所谓“特设多态”(方法重载)和“强制多态”(类型转换)我都放在后面作为非常规办法,这种办法都是动态的
大家谈论“继承”或“组合”,都集中在面向对象领域,但参数检测其实就是面向函数领域的“继承”或“组合”
多参数问题
一个函数可以一口气处理多个对象,一个对象也可以一口气调用多个方法
多个对象/多个方法传入,不就是打包成了单个嘛
参数或管道:数据”绑定“操作
#方法链
中文、英文的语序,主语、谓语、宾语——1.add(2)
日语、维吾尔语的语序,主语、宾语、谓语——1.<2>add
编程语言、阿拉伯语的语序,谓语、主语、宾语——add(1,2)
当返回值是个名词(数据,用作主语或宾语)
如果采用“主——谓”结构(宾语仅用于修饰),则可写出一长串方法链。例如
获得图像(输入源地址).高斯滤波(参考半径).颜色提取(参考颜色).黑白二值化().形态学变换(参考形状).输出显示(显示端口号)
就像流水线一样十分优雅,更改处理过程,只需要更改中间的环节就行了。
妙不可言!使用 Python 管道 Pipe 编写代码如此优雅! - 知乎
Python 开发神技 -- 使用管道 Pipe - 知乎
参数,这里指先写谓语,后写主语,后写宾语
管道,这里指先写主语,后写谓语,后写宾语
感觉管道写法,python的方法传递更符合自然语言顺序,其一行一行的形式又很像汇编语言,比数学语言还要直观。
主语.谓语(用=方式1, 宾语)
甲.和(乙).走(向=前方)
(甲, 乙).走(向=前方) # 元组解包
a.加(3).赋值给(b)
a.加上(2)
A.与(B.非()).或(C).赋值给(F)
A.与(非(B)).或(C).赋值给(F)
# 走势如图
# ↓ ↓
#-()-()→
本以为这种特性只有给类型动态添加方法才可做到
给函数添加参数、给对象添加方法,就是数据
和操作 建立联系过程中两个不同的视角
不修改原有类的情况下实现了类似“主谓宾”的方法链语法。fluentpy、toolz、pipe,这三个包都能做到低代码实现此语法糖,但是对于函数重载(例如Python封装的OpenCV库本质上还是C++写得)没什么办法!
有没有可能直接实现汇编代码变成Python风格,只需要一步编译就好了?
- 对于最小化的语句(例如MOV),“主语”是在缓存中或由缓存指向内存的数据,“谓语”是内存或ROM传入的指令,“宾语”是内存中的数据
- 对于复杂的方法,调用的实际上是PUSH(传参)和CALL(执行代码)
- 需要的:数据类型、内存分配规则,及其字面量表示声明
- 迈向其他符号体系:数学语言、自然语言