Python中的静态类变量和方法

567 阅读7分钟

Python中的静态类变量和方法

  • 如何在Python中创建静态类变量或方法?
  • 在Python中静态类变量是可能的吗?

🔍 实验。如果我们在Python文档中搜索*"静态类变量",我们将找不到任何接近于这些所谓的变量种类。如果我们尝试在文档的词汇表部分只搜索"static "这个词,我们会看到一些与"静态方法 "*有关的匹配,但没有与变量有关的匹配。

这是因为Python几乎不使用*"静态 "*这个词,而其他语言如C++Java则更常用这个词。

无论如何,由于不同的编程语言之间存在一些平行关系,我们将看到通常被理解为静态类变量和静态方法的东西在Python中是如何实现和工作的。这并不意味着详尽无遗,当然,掌握一些关于类和实例的基本概念是很方便的。

静态类变量

如果你已经有了一些想法,并且想简单地看看它是如何工作的,以及如何实现的,我建议你看下图,那里实际上都是总结出来的。

Static Class Variables

接下来,我们将用4个简单的步骤来探索这个图形中的代码。

第1步:Python中的类属性

如果我们试着总结一下*"静态类变量 "*在其他编程语言中的含义,我们可以这么说。

💡 定义。静态类变量是由一个类的所有实例共享的变量,这个变量只有一个副本,而不是在该类的每个实例中都有一个副本。

在 Python 中,通常把这个概念称为*"类属性",但也称为"属性类变量"、* "类变量",甚至,尽管不太常见,也称为*"静态变量 ""静态类变量"。在这里,为了使术语简单化,我们采用"类属性*"这一名称。

让我们看看如何在 Python 中创建和使用*"类属性"*。

在下面的例子中,我们将用一个叫做Employees 的类来模拟一家名为"A" 的公司的雇员。

class Employees:
    company = "A"   # class attribute
    languages = []

我们指出这个类的每个实例(每个具体的雇员)都属于公司"A" ,其类属性company ,其值为"A"

然后,我们创建另一个名为language 的*"类属性"*,作为一个空列表,以便以后存储每个雇员的母语。

你可能在想这应该是一个实例属性。但它在这里是为了帮助你看到,作为类属性的可变类型可以带来令人惊讶的结果。我们将在后面看到这一点。

步骤 2: Python 中的实例属性

正如你所看到的,它可以在类定义里面创建,就像你在 Python 中创建任何变量一样,但是在以def 开始的方法之外。

现在我们要用 [__init__()](https://blog.finxter.com/python-init/)属性 "n"(来自名称),类Employees 的每个对象(实例)都必须被初始化。

这些属性被称为*"数据属性 ""实例属性",对应于 C++ 中的数据成员*。

class Employees:
    company = "A"   # class atribute
    languages = []

    def __init__(self, name):
        self.n = name   # data or instance attribute

第三步:在 Python 中创建实例和打印类属性

好了,现在我们要添加代码来创建两个实例并打印它们的类属性。

class Employees:
    company = "A"   # class atribute
    languages = []
    def __init__(self, name):
        self.n = name   # data or instance atribute


e1 = Employees("Peter White")
e2 = Employees("Paul Green")
print(e1.company) # Result: A
print(e2.company) # Result: A

第4步:修改一个类属性

在Python中,我们可以在代码中改变一个*"类属性 "* 的值,并且这些改变将反映在所有的实例中,正如我们在下面的代码中所显示的。

# This code shows only what is added to the previous code and the results you will see
Employees.company = "B"   # Changing the value of the class attribute
print(e1.company) # Result: B
print(e2.company) # Result: B

第5步:修改一个类属性成为一个实例属性

而在 Python 中,我们可以将*"类属性 "*改为实例。这可能很罕见,但也是可能的,正如我们在下一个例子中展示的名为 "e1" 的实例。

# This code shows only what is added to the previous code and the results you will see
e1.company = "C"   # Changing the class attribute of the instance e1
print(e1.company) # Result: C
print(e2.company) # Result: B

第6步:理解可变的类属性

最后,我们不应该使用像列表字典这样的可变数据类型作为 "类属性",因为如果我们像下面的例子那样使用它们,它们可能会有令人惊讶的行为。

在这里,我们试图把每个雇员的母语作为一个类属性,并且以一个空列表开始。

很明显,这是一个 "实例属性",但是让我们对这个例子稍作调整,看看会发生什么。

# This code shows only what is added to the previous code and the results you will see
e1.language.append("english")
e2.language.append("spanish")
print(e1.language) # Result: ['english', 'spanish']
print(e2.language) # Result: ['english', 'spanish']

可以看出,没有得到预期的结果。

  • 一方面,这有助于理解母语是每个雇员的属性,也就是每个实例的属性,并且应该像"[self.n](https://blog.finxter.com/self-in-python/)"是在 [__init__()](https://blog.finxter.com/python-init/)方法内。
  • 另一方面,正如文档中第9.3.5点所述,这有助于看到将可变数据类型实现为 "类属性 "可能会产生令人惊讶的效果。

最后,我建议你看一下本节开头的图,我们试图在这里总结所有这些考虑。

静态方法

正如文档中所说,Python 中的静态方法与 Java 或 C++ 中的静态方法相似。

静态方法是一种可以在没有类的任何实例的情况下运行的方法。它不需要对一个特定的对象进行调用。

如果你想快速了解如何创建和使用静态方法,我建议你看下图,其中总结了最重要的内容。

Understanding static method Python example

最现代的Python实现,也就是我们在这里展示的那个,需要在 [@staticmethod](https://blog.finxter.com/python-staticmethod/)装饰器在启动方法的def 之前。

这告诉 Python 这是一个 "静态方法",而不是其他方法。

由于 "静态方法 "不修改或不需要类的实例来执行,所以它不需要像 "self"这样的参数,后者代表了调用方法时的实例本身。

💡 注意:我们澄清一下,使用术语"[self](https://blog.finxter.com/self-in-python/)"是一个惯例,可以使用另一个词,但这可能使代码的可读性降低,因为每个人都理解并期望在任何实例方法中看到一个"self"作为第一个参数。

让我们看一个例子,在这个例子中,我们重新学习了上一节中建立的Employees 类。为了展示一些简单的东西,我们将发明一个静态方法,当它被调用时返回程序的版本。

正如我们所看到的,没有必要创建一个实例来调用它。

class Employees:
    company = "A"
    def __init__(self,name):
        self.n = name

    @staticmethod
    def version():
        print("""Welcome to Company A's employee system.
This is the version 1.0
Type "Employees.help(1)" to see how to enter an object.""")

# To call this static method:
Employees.version()   # Result: Welcome to Company…

在前面的例子中,"静态方法 "没有参数。

让我们看看另一个,正如第一个 "静态方法 "信息所说,需要一个1来显示第一个帮助信息来创建一个对象或类的实例。

# This code shows only what is added to the previous code and the results you will see  
    @staticmethod
    def help(key):
        if key == 1:
            print("To create an object you can follow the next example by putting the employee's complete name in parentheses: e1 = Employees('John Black')")

# To call this static method:
Employees.help(1)   # Show: To create an object…

结论

我们已经看到了如何实现 "静态类变量",在 Python 中更多地被称为 "类属性"。

它们像任何变量一样简单地被创建,但在类的定义中,在创建方法的 "def" 之外。

我们也看到了类属性在 Python 中的一些特殊性。

另一方面,我们已经看到了如何实现 "静态方法",它不需要使用任何实例,使用 "@staticmethod" 装饰器在 "def" 之前,我们用它来开始定义方法本身。

我们还看到,它不需要 "self" 作为第一个参数。