python - 使用类方法在 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 种分配属性或计算数据的方法。在我的特定真实示例中,每种方法都执行复杂的计算,这些计算最好为了阅读代码目的而保持分隔。
我做的每一项任务都有一些缺点
方式一:
self.area = self._area()
。读者现在不知道在init方法中有多少变量需要面积来进行计算。运行一个类方法,但读者必须深入研究代码以查看计算的内容以及如何计算方式2:
self._squarearea(self.radius,self.area)
在这种情况下,读者不知道函数做了什么,即使函数设置了新的属性也是如此。相反,至少表明半径和面积被传递给函数。实际上传递的两个变量只是一个指示,因为在类方法中所有类属性都是可用的。方式3:
self.diameter = self._diameter(self.radius)
这里读者知道半径是pass,也知道分配了一个属性(直径)方式4:最后一种方式可以考虑为类的消费者提供调用方法
giveme4timesradius()
,但这很不方便,因为我希望所有内容都预先计算。每次调用时都必须计算它。
关于属性、类和教程有多个 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
解决方案
这是@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
推荐阅读
- r - 在 R 中创建具有多列的散点图
- python - 支持带有 aumbry 的加密和非加密配置
- cluster-analysis - 菊花出现“无效类型字符”错误
- java - Java中的斐波那契数列
- node.js - 由 heroku 调度程序创建的一次性测功机永远不会死亡(永远不会自杀,自杀......)
- c# - 如何将系统设计与单元测试分离(如 Bob 大叔建议的那样)?
- html - 在 CSS 中更改卡片大小
- linux - 在 bash 函数中模拟 Enter
- ios - 我如何知道应用程序是否通过 AppDelegate 的 didFinishLaunchingWithOptions 的 Firebase-Deeplink(动态链接)启动
- php - WP检查添加到html标签的特定类