除了名字以外,这些类之间有什么不同吗?
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__方法来声明变量值,会有任何区别吗?
我主要担心的是,我只会以一种方式使用它,而这会给我带来更多的问题。
正如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')
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 C:
one = 42
def __init__(self,val):
self.two=val
ci=C(50)
print(ci.__dict__)
print(C.__dict__)
结果是这样的:
{'two': 50}
{'__module__': '__main__', 'one': 42, '__init__': <function C.__init__ at 0x00000213069BF6A8>, '__dict__': <attribute '__dict__' of 'C' objects>, '__weakref__': <attribute '__weakref__' of 'C' objects>, '__doc__': None}
注意,我在这里设置了完整的结果,但重要的是,实例ci字典将只是{'two': 50},类字典将有'one': 42键值对在里面。
这是关于特定变量的所有信息。