Переменные внутри и вне функции 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).

319   5  

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

    Ничего не найдено.