除了名字以外,这些类之间有什么不同吗?
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 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引用只在没有相同名称的实例变量时引用静态类变量,更糟糕的是,试图通过Self引用重新定义静态类变量是行不通的,因为创建的实例变量会掩盖先前可访问的静态类变量。
要解决这个问题,您应该始终通过类名引用静态类变量。
例子:
#!/usr/bin/env python
class Foo:
static_var = 'every instance has access'
def __init__(self,name):
self.instance_var = 'I am %s' % name
def printAll(self):
print 'self.instance_var = %s' % self.instance_var
print 'self.static_var = %s' % self.static_var
print 'Foo.static_var = %s' % Foo.static_var
f1 = Foo('f1')
f1.printAll()
f1.static_var = 'Shadowing static_var'
f1.printAll()
f2 = Foo('f2')
f2.printAll()
Foo.static_var = 'modified class'
f1.printAll()
f2.printAll()
输出:
self.instance_var = I am f1
self.static_var = every instance has access
Foo.static_var = every instance has access
self.instance_var = I am f1
self.static_var = Shadowing static_var
Foo.static_var = every instance has access
self.instance_var = I am f2
self.static_var = every instance has access
Foo.static_var = every instance has access
self.instance_var = I am f1
self.static_var = Shadowing static_var
Foo.static_var = modified class
self.instance_var = I am f2
self.static_var = modified class
Foo.static_var = modified class
我希望这对某些人有所帮助
没有自我
创建一些对象:
class foo(object):
x = 'original class'
c1, c2 = foo(), foo()
我可以改变c1实例,它不会影响c2实例:
c1.x = 'changed instance'
c2.x
>>> 'original class'
但是如果我改变了foo类,该类的所有实例也会被改变:
foo.x = 'changed class'
c2.x
>>> 'changed class'
请注意Python作用域是如何工作的:
c1.x
>>> 'changed instance'
与自我
改变类不会影响实例:
class foo(object):
def __init__(self):
self.x = 'original self'
c1 = foo()
foo.x = 'changed class'
c1.x
>>> 'original self'
类就像创建对象的蓝图。让我们用建房子来做个比喻。你有房子的蓝图,所以你可以建造房子。你可以在资源允许的情况下建造尽可能多的房子。
在这个比喻中,蓝图是类,房子是类的实例化,创建一个对象。
这些房子有共同的属性,比如有屋顶、客厅等。这就是init方法的作用。它用你想要的属性构造对象(房子)。
让我们假设你有:
`class house:`
`roof = True`
`def __init__(self, color):`
`self.wallcolor = color`
>>创建小金锁的房子:
>> goldlock = house() #() invoke's class house, not function
>> goldlock.roof
>> True
all house's have roofs, now let's define goldlock's wall color to white:
>> goldlock.wallcolor = 'white'
>>goldlock.wallcolor
>> 'white'
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)在不同的状态,我们谈到,我认为这将使事情更好]
这就是我们真实的生活。儿子从父亲那里继承了一些信仰,这些信仰在儿子决定改变之前仍然与父亲的信仰相同。
希望对大家有所帮助