除了名字以外,这些类之间有什么不同吗?

class WithClass ():
    def __init__(self):
        self.value = "Bob"
    def my_func(self):
        print(self.value)

class WithoutClass ():
    value = "Bob"

    def my_func(self):
        print(self.value)

如果我使用或不使用__init__方法来声明变量值,会有任何区别吗?

我主要担心的是,我只会以一种方式使用它,而这会给我带来更多的问题。


当前回答

class foo(object):
    mStatic = 12

    def __init__(self):
        self.x = "OBj"

考虑到foo根本无法访问x(事实)

现在的冲突是通过实例或直接通过类访问mStatic。

从Python内存管理的角度来考虑:

12的值在内存中,名称mStatic(可以从类中访问)

指向它。

c1, c2 = foo(), foo() 

这一行创建了两个实例,其中包括指向值12的名称mStatic(到目前为止)。

foo.mStatic = 99 

这使得mStatic name指向内存中值为99的新位置。

因为(婴儿)c1 c2仍然在(爸爸)foo后面,所以它们有相同的名字(c1。mStatic & c2。mStatic)指向相同的新值。

但一旦每个宝宝决定独自走路,情况就不同了:

c1.mStatic ="c1 Control"
c2.mStatic ="c2 Control"

从现在到以后,该家族中的每一个(c1,c2,foo)都有它的mStatica指向不同的值。

[请尝试使用id()函数为所有(c1,c2,foo)在不同的状态,我们谈到,我认为这将使事情更好]

这就是我们真实的生活。儿子从父亲那里继承了一些信仰,这些信仰在儿子决定改变之前仍然与父亲的信仰相同。

希望对大家有所帮助

其他回答

正如S.Lott所指出的,

在init之外设置的变量属于该类。它们由 所有实例。 在init(和所有其他方法函数)中创建的变量和 以自我开头。属于对象实例。

然而, 注意,类变量可以通过self访问。<var>,直到它们被一个具有类似名称的对象变量所掩盖。<var>在给它赋值之前将返回Class的值。<var>但之后它将返回obj。< var >。这里有一个例子

In [20]: class MyClass: 
    ...:     elem = 123 
    ...:  
    ...:     def update(self,i): 
    ...:         self.elem=i  
    ...:     def print(self): 
    ...:         print (MyClass.elem, self.elem) 
    ...:  
    ...: c1 = MyClass()  
    ...: c2 = MyClass() 
    ...: c1.print() 
    ...: c2.print()                                                                                                                                                                                                                                                               
123 123 
123 123 
In [21]: c1.update(1) 
    ...: c2.update(42) 
    ...: c1.print() 
    ...: c2.print()                                                                                                                                                                                                                                                               
123 1 
123 42
In [22]: MyClass.elem=22 
    ...: c1.print()  
    ...: c2.print()                                                                                                                                                                                                                                                               
22 1 
22 42

第二个注意事项:考虑插槽。它们可能提供了更好的实现对象变量的方法。

class User(object):
    email = 'none'
    firstname = 'none'
    lastname = 'none'

    def __init__(self, email=None, firstname=None, lastname=None):
        self.email = email
        self.firstname = firstname
        self.lastname = lastname

    @classmethod
    def print_var(cls, obj):
        print ("obj.email obj.firstname obj.lastname")
        print(obj.email, obj.firstname, obj.lastname)
        print("cls.email cls.firstname cls.lastname")
        print(cls.email, cls.firstname, cls.lastname)

u1 = User(email='abc@xyz', firstname='first', lastname='last')
User.print_var(u1)

在上面的代码中,User类有3个全局变量,每个变量的值都是“none”。U1是通过实例化该类创建的对象。print_var方法输出User类变量的值和u1对象变量的值。在下面的输出中,每个类变量都是User。电子邮件、用户。firstname和User。Lastname的值为“none”,而对象变量为u1。电子邮件,u1。Firstname和u1。姓氏有值“abc@xyz”,“first”和“last”。

obj.email obj.firstname obj.lastname
('abc@xyz', 'first', 'last')
cls.email cls.firstname cls.lastname
('none', 'none', 'none')

在__init__之外设置的变量属于类。它们由所有实例共享。

在__init__(以及所有其他方法函数)中创建并以self为前缀的变量。属于对象实例。

在Python中,类带有成员函数(方法)、类变量、属性/实例变量(可能还有类方法):

class Employee:

    # Class Variable
    company = "mycompany.com"

    def __init__(self, first_name, last_name, position):
        # Instance Variables
        self._first_name = first_name
        self._last_name = last_name
        self._position = position

    # Member function
    def get_full_name(self):
        return f"{self._first_name} {self._last_name}"

通过创建对象的实例

my_employee = Employee("John", "Wood", "Software Engineer")

我们实际上触发了__init__,它将初始化新创建的Employee的实例变量。这意味着_first_name, _last_name和_position是特定my_employee实例的显式参数。

同样,成员函数返回信息或更改特定实例的状态。


现在,在构造函数__init__之外定义的任何变量都被认为是类变量。这些变量在类的所有实例之间共享。

john = Employee("John", "Wood", "Software Engineer")
bob = Employee("Bob", "Smith", "DevOps Engineer0")

print(john.get_full_name())
print(bob.get_full_name())
print(john.company)
print(bob.company)

>>> John Wood
>>> Bob Smith
>>> mycompany.com
>>> mycompany.com

您还可以使用类方法来更改类的所有实例的类变量。例如:

@classmethod
def change_my_companys_name(cls, name):
    cls.company = name

现在输入change_my_companys_name()

bob.change_my_companys_name("mynewcompany.com")

将对类Employee的所有实例产生影响:

print(bob.company)
print(john.company)

>>> mynewcompany.com
>>> mynewcompany.com
class foo(object):
    mStatic = 12

    def __init__(self):
        self.x = "OBj"

考虑到foo根本无法访问x(事实)

现在的冲突是通过实例或直接通过类访问mStatic。

从Python内存管理的角度来考虑:

12的值在内存中,名称mStatic(可以从类中访问)

指向它。

c1, c2 = foo(), foo() 

这一行创建了两个实例,其中包括指向值12的名称mStatic(到目前为止)。

foo.mStatic = 99 

这使得mStatic name指向内存中值为99的新位置。

因为(婴儿)c1 c2仍然在(爸爸)foo后面,所以它们有相同的名字(c1。mStatic & c2。mStatic)指向相同的新值。

但一旦每个宝宝决定独自走路,情况就不同了:

c1.mStatic ="c1 Control"
c2.mStatic ="c2 Control"

从现在到以后,该家族中的每一个(c1,c2,foo)都有它的mStatica指向不同的值。

[请尝试使用id()函数为所有(c1,c2,foo)在不同的状态,我们谈到,我认为这将使事情更好]

这就是我们真实的生活。儿子从父亲那里继承了一些信仰,这些信仰在儿子决定改变之前仍然与父亲的信仰相同。

希望对大家有所帮助