首页 > 解决方案 > 使用类方法在 PYTHON 类中分配属性值

问题描述

这是一个与设置属性有关的非常基本的问题,我没有找到明确的答案。我有一个python类如下

class circle():
    
    PI = 3.14
    
    def __init__(self,radius):
        self.radius   = radius
        # 1. first way of assigning an atribute
        self.area     = self._area()
        # 2. second way of assigning an attribute (running a method)
        self._squarearea(self.radius,self.area)
        # 3. third way of assigning an attribute
        self.diameter = self._diameter(self.radius)
        
    def _area(self):
        return self.radius * self.PI * self.PI
    
    def _squarearea(self,radius,area):
        self.sqarea = radius * radius * 4 - area
        
    def _diameter(self,radius):
        return self.radius *2

    def giveme4timesradius(self):
        return 4*self.radius

我列出了 4 种分配属性或计算数据的方法。在我的特定真实示例中,每种方法都执行复杂的计算,这些计算最好为了阅读代码目的而保持分隔。

我做的每一项任务都有一些缺点

关于属性、类和教程有多个 SO 问题(见下文),但我在任何地方都没有看到这种比较。我认为我不需要任何 setter 和 getter,因为我只想从一开始就运行所有内容,根据倍数条件,某些属性将使用某些类方法或其他方法计算。

那么“pythonic”方式有哪些方式?还是其中任何一个?

参考资料:
https ://www.toptal.com/python/python-class-attributes-an-overly-thorough-guide
https://realpython.com/lessons/adding-attributes-python-class/
https://www .python-course.eu/python3_class_and_instance_attributes.php
https://medium.com/shecodeafrica/managing-class-attributes-in-python-c42d501c5ee0

标签: pythonclasspropertiesattributesclass-method

解决方案


这是@property装饰器的一个很好的用例。

class Circle():
    
    PI = 3.14
    
    def __init__(self,radius):
        self.radius   = radius
    
    @property
    def area(self):
        return self.radius * (self.PI ** 2)
    
    @property
    def squarearea(self):
        return (self.radius ** 2)  * 4 - self.area
    
    @property
    def diameter(self):
        return self.radius *2
    
    @property
    def giveme4timesradius(self):
        return 4*self.radius

另外作为我的偏好,我会使用@dataclass:

from dataclasses import dataclass
from typing import ClassVar

@dataclass
class Circle():

    radius: float
    PI: ClassVar[float] = 3.14

    # No need __init__ -> handled by dataclass
    
    @property
    def area(self):
        return self.radius * (self.PI ** 2)
    
    @property
    def squarearea(self):
        return (self.radius ** 2)  * 4 - self.area
    
    @property
    def diameter(self):
        return self.radius *2
    
    @property
    def giveme4timesradius(self):
        return 4*self.radius

推荐阅读