Python类方法点号调用与实例传参调用的区别及适用场景
问题解答
对应DFS实现代码
class Node: def __init__(self, name): self.children = [] self.name = name def addChild(self, name): self.children.append(Node(name)) #recall I came across this before- 'Node(name)' is a node return self def depthFirstSearch(self, array): #self in this case is the root array.append(self.name) for child in self.children: child.depthFirstSearch(array) return array
疑问1:child.depthFirstSearch(array)和depthFirstSearch(child,array)是否等价?
二者并不等价,你写的第二种写法甚至会直接触发NameError运行报错。
原因是depthFirstSearch是定义在Node类内部的实例方法,不属于全局命名空间,直接调用depthFirstSearch(...)时解释器找不到这个函数。
而点号调用是Python的内置语法糖:child.depthFirstSearch(array)本质和Node.depthFirstSearch(child, array)完全等价,解释器会自动把调用方法的实例child作为第一个参数self传入类方法中。如果你写的是后者形式的类方法调用,那和点号调用效果完全一致。
疑问2:第二种写法会不会无法访问child.children?
如果你用的是正确的类方法调用形式Node.depthFirstSearch(child, array),完全可以正常访问child.children:方法内的self参数此时就是你传入的child实例,self.children就对应child.children,不存在访问障碍。
如果你是自行把depthFirstSearch抽成全局函数,只要第一个参数传入的是合法的Node实例,也能正常访问实例的所有成员。
疑问3:什么时候需要用点号调用?能不能不用?
- 点号是Python中访问对象成员(包括属性、方法)的默认运算符,只要你要调用的方法、访问的属性属于某个类实例/类本身,都可以用点号调用,这是可读性最高、最符合Python语法规范的写法。
- 不想用点号也可以实现,比如用反射函数
getattr:getattr(child, "depthFirstSearch")(array),或者直接调用类方法手动传入self参数,也就是前面提到的Node.depthFirstSearch(child, array),但这些写法可读性远低于点号调用,没有特殊需求不建议使用。
内容的提问来源于stack exchange,提问作者Patrick_Chong
相关产品推荐
相关产品推荐

