Python中Spark的catalog属性为何可调用listTables()等方法
解答
你产生这个疑惑本质是把「属性」的取值范围想窄了。Python是动态类型语言,类的实例属性没有类型限制,不是只能存储数字、字符串这类基础值,完全可以存储任意类型的Python对象——包括其他类的实例。而一个类的实例本身就可以自带方法,当属性存的是这类实例对象时,自然就支持在属性后面继续调用它自己的方法,链式调用本质只是把两步取值、调用的操作连写了而已,没有任何特殊语法魔法。
给你写个最小复现示例,看完就能完全理解逻辑:
# 先定义负责表/元数据操作的Catalog类,收敛所有和 catalog 相关的能力 class Catalog: def listTables(self): # 模拟返回集群表列表的逻辑 return ["user_basic", "order_flow", "product_lib"] # 定义SparkSession类 class SparkSession: def __init__(self): # catalog是SparkSession的实例属性,值就是提前初始化好的Catalog类实例 self.catalog = Catalog()
你看到的spark.catalog.listTables()调用,完全可以拆成两步独立操作,运行效果没有任何区别:
spark = SparkSession() # 第一步:取spark实例的catalog属性,拿到Catalog类的实例对象 catalog_obj = spark.catalog # 第二步:对Catalog实例调用它自身绑定的listTables方法 print(catalog_obj.listTables()) # 输出:['user_basic', 'order_flow', 'product_lib']
所谓的链式调用只是省略了中间变量,直接在取到的属性值上继续调方法而已。
这种设计在Python生态里非常常见,属于面向对象组合模式的常规用法:把不同职责的逻辑拆分到独立类里,避免单个类的方法过于庞杂。你日常用的很多库都有同类写法:
- pandas里的
series.str.contains("关键词"),str就是Series实例的属性,存的是字符串处理专属的StringMethods类实例,contains()就是该实例的方法 - Python内置文件对象的
f.buffer.read(),buffer是文件实例的属性,存的是二进制缓冲类实例,read()是缓冲实例的方法
内容的提问来源于stack exchange,提问作者brian
相关产品推荐
相关产品推荐

