Переменные внутри и вне функции init () класса
Я пытаюсь понять, есть ли вообще разница между этими классами кроме названия? Имеет ли значение, если я использую или не использую функцию __init__() при объявлении переменной "value"?
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).
5 ответов:
переменной, которая находится за пределами
__init__относятся к классу. Они являются общими для всех экземпляров.переменные, созданные внутри
__init__(и все другие функции метода) и предваряетсяself.принадлежат экземпляру объекта.
Не
создать некоторые объекты:
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__:это, по сути, статические переменные класса и, следовательно, доступны для всех экземпляров класса.
переменные внутри
__init__:значение этих переменные доступны только для экземпляра под рукой (через
selfссылка)мой вклад:
одна вещь, которую программисты должны учитывать при использовании статические переменные класса это то, что они могут быть затенены переменные (если вы обращаетесь к статические переменные класса до
selfссылка.)объяснение:
ранее я думал, что оба способа объявления переменных были точно такими же (глупый я), и это было отчасти потому, что я мог получить доступ к обоим видам переменных через
selfссылка. Именно сейчас, когда я столкнулся с проблемой, я исследовал эту тему и прояснил ее.проблема с доступом статические переменные класса через
selfссылка в том, что это только ссылки на статическая переменная класса если нет переменная С тем же именем, и чтобы сделать вещи хуже, пытаясь переопределить статическая переменная класса доselfссылка не работает, потому что переменная создается который затем затеняет ранее-доступный статическая переменная класса.чтобы обойти эту проблему, вы всегда должны ссылаться статический класс переменные через имя класса.
пример:
#!/usr/bin/env python class Foo: static_var = 'every instance has access' def __init__(self,name): self.instance_var = 'I am ' % 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Я надеюсь, что это полезно для кого-то
в дополнение к ответу S. Lott, переменные класса передаются в metaclass новая метод и могут быть доступны через словарь, когда метакласс определен. Таким образом, переменные класса могут быть доступны еще до создания и создания экземпляров классов.
например:
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 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'. У1-это объект, созданный путем создания экземпляра этого класса. Метод print_var выводит значения переменных класса класса User и переменных объекта объекта 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')
Comments