You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否用列表推导式同时实现类实例化与方法调用?

问题描述

我写了一个计算正四棱锥侧面积和体积的简单程序:

from math import sqrt  # 补充原代码遗漏的导入

class RightSquarePyramid():
    def __init__(self, b=0, h=0):
        self.b = float(b)
        self.h = float(h)
    
    def slantHeight(self):
        self.l = sqrt((self.h ** 2 + (self.b / 2) ** 2))
        return self.l
    
    def lateralSurfaceArea(self):
        return 2 * self.b * self.l
    
    def volume(self):
        return 1/3 * self.b ** 2 * self.h

myList = [[2.5, 5.0], [4.3, 2.5], [8, 3]]

tri0, tri1, tri2 = [RightSquarePyramid(*x) for x in myList]
tri0.slantHeight()
tri1.slantHeight()
tri2.slantHeight()
print(round(tri0.lateralSurfaceArea(), 3), round(tri1.lateralSurfaceArea(), 3), round(tri2.lateralSurfaceArea(), 3))
print(round(tri0.volume(), 3), round(tri1.volume(), 3), round(tri2.volume(), 3))

因为已知的只有棱锥的高度和底面边长,必须先计算斜高才能求侧面积。我现在把三次方法调用改成了列表推导式,但只是从3行缩成2行:

tri0, tri1, tri2 = [RightSquarePyramid(*x) for x in myList]
triForce = tri0, tri1, tri2
[x.slantHeight() for x in triForce]
print(round(tri0.lateralSurfaceArea(), 3), round(tri1.lateralSurfaceArea(), 3), round(tri2.lateralSurfaceArea(), 3))
print(round(tri0.volume(), 3), round(tri1.volume(), 3), round(tri2.volume(), 3))

我想知道能不能用一个列表推导式同时完成实例化和slantHeight()的调用?有没有什么通用写法可以实现这个需求?


解决方案

当然可以,下面提供两种思路,其中修改类设计的方式更推荐:

方法1:单列表推导式完成实例化+方法调用

利用Python表达式的特性,在推导式里先创建实例,调用slantHeight()(该方法会修改实例属性),同时保留实例本身:

from math import sqrt

class RightSquarePyramid():
    # 类定义与原代码一致
    def __init__(self, b=0, h=0):
        self.b = float(b)
        self.h = float(h)
    
    def slantHeight(self):
        self.l = sqrt((self.h ** 2 + (self.b / 2) ** 2))
        return self.l
    
    def lateralSurfaceArea(self):
        return 2 * self.b * self.l
    
    def volume(self):
        return 1/3 * self.b ** 2 * self.h

myList = [[2.5, 5.0], [4.3, 2.5], [8, 3]]

# 单列表推导式完成实例化+调用slantHeight
tri0, tri1, tri2 = [(obj.slantHeight(), obj)[1] for obj in [RightSquarePyramid(*x) for x in myList]]

# 或者更简洁的写法(利用斜高不为0的特性)
# tri0, tri1, tri2 = [obj.slantHeight() or obj for obj in [RightSquarePyramid(*x) for x in myList]]

print(round(tri0.lateralSurfaceArea(), 3), round(tri1.lateralSurfaceArea(), 3), round(tri2.lateralSurfaceArea(), 3))
print(round(tri0.volume(), 3), round(tri1.volume(), 3), round(tri2.volume(), 3))

解释:obj.slantHeight()会计算并赋值self.l,返回斜高值。我们通过(obj.slantHeight(), obj)[1]取到实例本身,最终推导式的结果就是已经计算好斜高的实例列表。

方法2:修改类设计(更健壮)

更好的方式是消除“必须提前调用slantHeight()”的依赖,让类自身处理斜高的计算:

from math import sqrt

class RightSquarePyramid():
    def __init__(self, b=0, h=0):
        self.b = float(b)
        self.h = float(h)
    
    @property
    def slant_height(self):
        # 用@property装饰器,每次访问自动计算斜高
        return sqrt((self.h ** 2 + (self.b / 2) ** 2))
    
    def lateralSurfaceArea(self):
        # 直接使用slant_height属性,无需提前调用方法
        return 2 * self.b * self.slant_height
    
    def volume(self):
        return 1/3 * self.b ** 2 * self.h

myList = [[2.5, 5.0], [4.3, 2.5], [8, 3]]

# 仅需实例化,无需额外操作
tri0, tri1, tri2 = [RightSquarePyramid(*x) for x in myList]
print(round(tri0.lateralSurfaceArea(), 3), round(tri1.lateralSurfaceArea(), 3), round(tri2.lateralSurfaceArea(), 3))
print(round(tri0.volume(), 3), round(tri1.volume(), 3), round(tri2.volume(), 3))

这种设计更符合面向对象的原则,避免了外部调用的依赖,代码更简洁健壮。


内容的提问来源于stack exchange,提问作者xQT314

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 11:34:52