Python _uu init__;()内部和外部变量之间的差异
除了名称之外,这些类之间还有什么区别吗Python _uu init__;()内部和外部变量之间的差异,python,class,oop,constructor,Python,Class,Oop,Constructor,除了名称之外,这些类之间还有什么区别吗 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) 如果我使用或不使用\uuuu in
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)
如果我使用或不使用\uuuu init\uuu
方法来声明变量值
,会有什么区别吗
我主要担心的是,我将以一种方式使用它,而这将给我带来更多的问题。在
\uuuuuu init\uuuuu>之外设置的变量属于该类。它们被所有实例共享
在\uuuu init\uuuu
(以及所有其他方法函数)中创建并以self.
开头的变量属于对象实例 继S.Lott的回答之后,类变量被传递给元类new方法,并且在定义元类时可以通过字典访问。因此,即使在创建和实例化类之前,也可以访问类变量
例如:
class meta(type):
def __new__(cls,name,bases,dicto):
# two chars missing in original of next line ...
if dicto['class_var'] == 'A':
print 'There'
class proxyclass(object):
class_var = 'A'
__metaclass__ = meta
...
...
没有自我
创建一些对象:
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'
我想在我在这篇文章中读到的回复中添加一些东西(引用了这篇文章)
免责声明:这句话来自于我进行的实验
变量在\uuuuu init\uuuu
之外:
#!/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
事实上,这些是静态类变量,因此可以访问该类的所有实例
内部变量\uuuu init\uuuu
:
#!/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
这些实例变量的值仅可由手头的实例访问(通过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
<> P>程序员在使用静态类变量时必须考虑的一件事是,它们可以被实例变量遮蔽(如果您通过“代码> >“自我/代码>引用”访问静态类变量)。
说明:
#!/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
在此之前,我认为声明变量的两种方式完全相同(愚蠢的我),这部分是因为我可以通过self
引用访问这两种变量。现在,当我遇到麻烦时,我研究了这个话题并澄清了它
通过
self
reference是指如果没有同名的实例变量,它只引用静态类变量,更糟糕的是,尝试通过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
输出:
#!/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 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方法打印类用户的类变量值和对象u1的对象变量值。在下面显示的输出中,每个类变量User.email
、User.firstname
和User.lastname
都有值'none'
,而对象变量u1.email
、u1.firstname
和u1.lastname
都有值abc@xyz“
,'first'
和'last'
obj.email obj.firstname obj.lastname
('abc@xyz', 'first', 'last')
cls.email cls.firstname cls.lastname
('none', 'none', 'none')
如果跟踪类和实例字典,这很容易理解
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}
{'two':50}
{“模块”:“主模块”:“一”:42,“初始模块”:“指令模块”:“weakref”:“无”
注意:我在这里设置了完整的结果,但重要的是实例ci
dict将只是{'two':50}
,并且类字典中将包含'one':42
键值对
这就是关于特定变量的所有知识。类就像创建对象的蓝图。让我们用盖房子来比喻一下。你有房子的蓝图,这样你就可以盖房子了。你可以在你的资源允许的情况下建造尽可能多的房子
在这个比喻中,蓝图是类,房子是类的实例化,创建一个对象
这些房子有一些共同的属性,比如有屋顶、起居室等。这就是使用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'
在Python中,类附带了成员函数(方法)、类变量、属性/实例变量(可能还有类方法):
通过创建对象的实例
my_employee = Employee("John", "Wood", "Software Engineer")
我们本质上触发了\uuuu init\uuuu
,它将初始化新创建的员工的实例变量。这意味着\u first\u name
、\u last\u name
和\u position
是特定我的员工
实例的显式参数
同样,成员函数返回信息或更改特定实例的状态
现在,在构造函数\uuuu init\uuuu
之外定义的任何变量都被视为类变量。这些变量在类的所有实例中共享
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
现在更改我公司的名称()
将对类员工的所有实例生效:
print(bob.company)
print(john.company)
>>> mynewcompany.com
>>> mynewcompany.com
考虑到foo根本无法访问x(F