oop - 类成员变量不和全局变量一样糟糕吗?

标签 oop global-variables member member-variables

我们都知道下面的代码由于使用了全局变量而不好:

a = 3.14

def inc():
  global a
  a += 1

inc()
b = a

这太糟糕了,在 python 中,人们必须故意声明 global 来“打破”禁令。但以面向对象的名义,为什么下面的代码是合理的:

class A:
  def __init__(self):
    self.a = 3.14

  def inc(self):
    self.a += 1

A_instance = A()
A_instance.inc()
b = A_instance.a

在类实例的范围内,成员变量不就和全局变量一样了吗? “self”基本上将无限制地访问 all 变量给 any 成员函数,无论是否有必要,这使得它非常有状态,容易出错,并且难以阅读(基本上是所有不好的东西)全局变量的特征)?

我们还知道干净且更好的方法是:

def inc(_a):
  return _a+1

a = 3.14
b = inc(a)

这样函数 inc() 至少是无状态的并且具有可预测的行为。使用类并使其尽可能无状态的最佳实践是什么?或者根据定义,面向对象是否总是有状态的,并且必须在没有类的情况下进行函数式编程?我还听到人们说 @static 方法很愚蠢,破坏了封装,应该避免......

最佳答案

这取决于您是否需要保存状态。如果您确实需要保存状态,那么需要将其保存在某个地方。类允许您将状态与操作该状态的方法一起保存,并强制执行类本地范围,该范围比在全局范围内存储状态更不易出错。

作为一个具体的例子,我最近实现了一个用于森林模拟的 Tree 类。与树相关的重要变量之一是它的年龄。树龄应该存储在哪里?将其存储在 Tree 类中比存储在其外部更有意义。

如果保护树的年龄不被类外部的代码操纵很重要,我可以使用 Python 优秀的 @property 语法来实现此目的,或者直接通过 Python _varname 变量命名约定。

在类中,是的,树的年龄对其他方法是可见的,但这是一个相对狭窄的范围,如果您的类是根据 SOLID 对象以单一职责编写的,那么肯定不类似于全局范围面向设计原则。

关于oop - 类成员变量不和全局变量一样糟糕吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59571073/

相关文章:

c# - 如何将显示成员设置为串联表达式?数据源是linq查询

php - 为什么公共(public)函数可以通过静态调用来访问 - PHP?

c# - 如何向文字对象添加方法和字段?

java - 类中的字段不是类似于全局变量吗?

javascript - 如何在不使用全局变量的情况下在 javascript 中存储和访问 ajax 数据?

c# - 声明 C# 属性

java - 代码说明 : DataModel model = new FileDataModel (new File ("intro.csv"));

c++ - 避免重写方法中的突变

c++ - 'extern' 关键字的作用是什么使以下代码合法?

Python:如何引用成员变量