我可以在构造函数方法之外声明 Python 类字段吗?

And*_*ili 7 python python-3.x python-object

我绝对是 Python 新手(我来自 Java),我对类字段有以下疑问。

考虑这样的代码:

class Toy():
    def __init__(self, color, age):
        self.color = color
        self.age = age

action_figure = Toy('red', 10)
Run Code Online (Sandbox Code Playgroud)

好的,做了什么很清楚而且很简单:

它正在定义一个玩具类。在构造方法中定义了两个字段以及如何设置字段值。最后(在“main”中)它创建了一个新的Toy实例,在构造函数调用中传递该字段的值。

好的,明白了……但我有疑问。在 Java 中定义相同的类我做这样的事情:

public class Toy {
    private String color;
    private int age;

    // CONSTRUCTOR:
    public Dog(String color, int age) {
        this.color = color;
        this.age = age;
    }
}
Run Code Online (Sandbox Code Playgroud)

好吧,它很相似,但我发现了一个很大的区别。在我的 Java conde 中,我将类字段声明为我的构造函数方法之外的变量。在 Python 中,我直接在构造函数方法中定义类字段。所以这意味着在 Java 中我可以声明 n 个类字段并使用构造函数方法只初始化这个字段的一个子集,例如这样的:

public class Toy {
    private String color;
    private int age;
    private String field3;
    private String field4;
    private String field5;

    // CONSTRUCTOR:
    public Dog(String color, int age) {
        this.color = color;
        this.age = age;
    }
}
Run Code Online (Sandbox Code Playgroud)

我还有field3field4field5字段,它们不会被我的构造函数初始化(以防我可以使用 setter 方法第二次设置它们的值)。

我可以在 Python 中做类似的事情吗?我可以在构造函数方法之外声明类字段吗?

Piy*_*ngh 10

Classes in python vs in c++/java are fundamentally different in that a c++/java class has a fixed data structure and size (bytes) because each attribute is declared or defined outside of all methods (normally as private variables) but in python everything is on the fly(dynamically typed).

lnstance variables (anything with self. ) can be defined only in methods. Choice of defining attribute in constructor vs other methods is about other people being able to quickly understand your code/data structure (although due to dynamic-ness calling python classes data structures would be inappropriate)

As an example of dynamic-ness You can even add new methods and attributes to classes and even instances at run time:

class A:
    pass
Run Code Online (Sandbox Code Playgroud)

Adding stuff to a class at runtime (These will be added to all existing and future instances of the class):

A.key = val

def f(self):
    return 0

A.myfunction = f
a = A()
a.myfunction()
# 0
Run Code Online (Sandbox Code Playgroud)

Adding stuff to a single instance at runtime:

a=A()
a.attr='something'

def f(self):
    return 0

a.fun=f.__get__(a)
a.fun()
# 0
Run Code Online (Sandbox Code Playgroud)


ste*_*sia 6

在 python 中,你可以做这样的事情:

class Toy():
    def__init__(self, color, age):
        self.color = color
        self.age = age

    def another_method(self, f):
         self.field3 = f + 4
         return self.field3
Run Code Online (Sandbox Code Playgroud)

但通常建议为清楚起见(更多参数在这里:https : //stackoverflow.com/a/38378757/4709400)在构造函数中初始化所有实例变量,所以你会这样做:

class Toy():
    def__init__(self, color, age):
        self.color = color
        self.age = age
        self.field3 = None
        self.field4 = 0 # for instance
        self.field5 = "" # for instance

    def another_method(self, f):
         self.field3 = f + 4
         return self.field3
Run Code Online (Sandbox Code Playgroud)