programing

__init__()의 내부 변수와 외부 변수 간의 차이(클래스 및 인스턴스 속성)

lastmoon 2023. 6. 21. 22:56
반응형

__init__()의 내부 변수와 외부 변수 간의 차이(클래스 및 인스턴스 속성)

이 수업들 사이에 이름 외에 다른 점이 있습니까?

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__ 수 변 법방언을 하는 방법value?

저의 주된 걱정은 제가 그것을 일방적으로 사용하게 될 것이라는 것입니다. 그러면 앞으로 더 많은 문제가 생길 것입니다.

외부의 변수 집합__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'

이 스레드에서 읽은 응답과 이 스레드(이 스레드를 참조)에 추가하고 싶습니다.

고지 사항: 이 발언은 제가 실행한 실험에서 나온 것입니다.

외부 변수:

이러한 변수는 실제로 정적 클래스 변수이므로 클래스의 모든 인스턴스에 액세스할 수 있습니다.

내부 변수:

이러한 인스턴스 변수의 값은 다음을 통해 현재 인스턴스에만 액세스할 수 있습니다.self참조)

의 기여:

정적 클래스 변수를 사용할 때 프로그래머가 고려해야 하는 한 가지 사항은 인스턴스 변수에 의해 음영 처리될 수 있다는 것입니다.self참조).

설명:

하는 두 me), 으로는 'sily me'(sily me)를 두 할 수 입니다. 부분적으로는 두 가지 변수에 모두 액세스할 수 있기 때문입니다.self언급는 그 제가 문제에 부딪혔을 때, 저는 그 주제를 조사하고 그것을 해결했습니다.

를 통해 정적 클래스 변수에 액세스하는 문제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

이것이 누군가에게 도움이 되기를 바랍니다.

더 멀리 S까지Lott의 응답, 클래스 변수는 메타클래스 새 메서드로 전달되며 메타클래스가 정의될 때 사전을 통해 액세스할 수 있습니다.따라서 클래스를 만들고 인스턴스화하기 전에도 클래스 변수에 액세스할 수 있습니다.

예:

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)

위의 코드에서 사용자 클래스는 각각 값이 '없음'인 3개의 전역 변수를 가집니다.u1은 이 클래스를 인스턴스화하여 만든 개체입니다.과 object print_var의 객체 값을 합니다.의 클래스 변수는 " " " " 입니다.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 Employee:

    # Class Variable
    company = "mycompany.com"

    def __init__(self, first_name, last_name, position):
        # Instance Variables
        self._first_name = first_name
        self._last_name = last_name
        self._position = position

    # Member function
    def get_full_name(self):
        return f"{self._first_name} {self._last_name}"

객체의 인스턴스를 생성함으로써

my_employee = Employee("John", "Wood", "Software Engineer")

우리는 근본적으로 유발합니다.__init__새로 생성된 인스턴스 변수를 초기화합니다.Employee은 즉을 합니다._first_name,_last_name그리고._position특정 인스턴스의 명시적 매개 변수입니다.

마찬가지로 구성원 함수는 정보를 반환하거나 특정 인스턴스의 상태를 변경합니다.


이 자 외 정 모 든 변__init__클래스 변수로 간주됩니다.이러한 변수는 클래스의 모든 인스턴스에서 공유됩니다.

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

그리고 지금은change_my_companys_name()

bob.change_my_companys_name("mynewcompany.com")

됩니다.Employee:

print(bob.company)
print(john.company)

>>> mynewcompany.com
>>> mynewcompany.com

코드 예제:

class inside:
    def __init__(self):
        self.l = []

    def insert(self, element):
        self.l.append(element)


class outside:
    l = []             # static variable - the same for all instances

    def insert(self, element):
        self.l.append(element)


def main():
    x = inside()
    x.insert(8)
    print(x.l)      # [8]
    y = inside()
    print(y.l)      # []
    # ----------------------------
    x = outside()
    x.insert(8)
    print(x.l)      # [8]
    y = outside()
    print(y.l)      # [8]           # here is the difference


if __name__ == '__main__':
    main()

클래스 및 인스턴스 사전을 추적하면 매우 쉽게 이해할 수 있습니다.

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}

여기에 인 " 참나여기전결체설과중만것인가은스스턴요한지하정고"입니다.cidict는 정당할 것입니다.{'two': 50} 수업 에는 그고수사그가것질다입니을것전은업리▁the▁have다것▁will▁andary니가 있을 것입니다.'one': 42키 값 쌍이 내부에 있습니다.

이것이 특정 변수에 대해 알아야 할 전부입니다.

클래스는 객체를 만들기 위한 청사진과 같습니다.집을 짓는 것으로 비유를 만들어 봅시다.당신은 집의 설계도를 가지고 있어서 집을 지을 수 있습니다.여러분은 자원이 허락하는 한 많은 집을 지을 수 있습니다.

이 비유에서 청사진은 클래스이고 집은 클래스의 인스턴스화로 객체를 만듭니다.

그 집들은 지붕, 거실 등의 공통적인 속성을 가지고 있습니다.여기서 init 메소드가 실행됩니다.원하는 속성으로 객체(하우스)를 구성합니다.

예를 들어 다음과 같습니다.

`class house:`
`roof = True`
`def __init__(self, color):`
`self.wallcolor = color`

>> create little goldlock's house:

>> 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에 전혀 접근할 수 없다는 점을 고려하면 (FACT)

인스턴스 또는 클래스에서 직접 mStatic에 액세스할 때 충돌이 발생합니다.

Python의 메모리 관리 측면에서 생각해 보십시오.

12 값은 메모리에 있고 이름은 mStatic입니다(클래스에서 액세스 가능).

그것을 가리킵니다.

c1, c2 = foo(), foo() 

이 선은 두 개의 인스턴스를 만듭니다. 여기에는 값 12(현재까지)를 가리키는 mStatic이라는 이름이 포함됩니다.

foo.mStatic = 99 

이것은 mStatic 이름이 메모리 안에 99라는 값을 가진 새로운 장소를 가리키도록 만듭니다.

그리고 (c1) c1, c2가 여전히 (c2) foo를 따르기 때문에, 그들은 같은 이름 (c1)을 갖습니다.m정적 & c2.m정적)이 동일한 새 값을 가리킵니다.

하지만 각각의 아기가 혼자 걷기로 결정하면, 상황은 다릅니다.

c1.mStatic ="c1 Control"
c2.mStatic ="c2 Control"

지금부터 그리고 나중에, 그 가족 (c1,c2,foo)의 각각은 다른 값을 가리키는 mStatica를 가지고 있습니다.

[제발, 우리가 이야기했던 다른 상태의 모든 (c1,c2,foo)에 대해 id() 함수를 사용해보세요, 저는 그것이 상황을 더 좋게 만들 것이라고 생각합니다.]

그리고 이것이 우리의 실제 삶의 방식입니다. 아들들은 그들의 아버지로부터 어떤 믿음들을 물려받습니다. 그리고 이러한 믿음들은 아들들이 그것을 바꾸기로 결정할 때까지 여전히 아버지의 믿음들과 동일합니다.

도움이 되길 바랍니다.

S가 지적한 바와 같이.로트,

init 외부에 설정된 변수가 클래스에 속합니다.모든 인스턴스에서 공유됩니다.

init(및 기타 모든 메서드 함수) 내부에 생성되고 self. 앞에 붙는 변수는 개체 인스턴스에 속합니다.

그러나 클래스 변수는 자체를 통해 액세스할 수 있습니다.비슷한 이름을 가진 객체 변수에 의해 마스킹될 까지 <var> 이것은 읽기 자아를 의미합니다.<var> 값을 할당하기 전에 클래스 값을 반환합니다.<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 test:
    f = 3

    def __init__(s, f):
        s.__class__.f = f
        s.f = s.__class__.f
        print(f'def __init__(s, {f})')
        print(f's.__class__.f = {f}')
        print(f's.f={s.__class__.f}')
        print(f'f={f}')
        print('===============init over===========')

    def setinstancetoOne(s, f):
        print(f'def setinstancetoOne(s, {f})')
        s.f = f

    print(f'class var f = {f}')

    def useClassname(test):
        print(f'>>>>def useClassname({test})')
        print(f'test.f {test.f}')

    def p_method(s):
        print(f'>>>>def p_method({s})')
        print(f's.f {s.f}')
        print(f'test.f {test.f}')
        print(f's.__class__.f {s.__class__.f}')

    print(f'class var f={f}')


# test.__init__.f = 19
t = test(2)
t.useClassname()
t.p_method()
print(f'Outside class t.f {t.f}')
print(f'Outside class test.f {test.f}')

print('______difference__________')
t = test(2)
t.setinstancetoOne(1)
t.useClass()
t.p_method()
print(f'Outside class instance variable(2) {t.f}')
print(f'Outside class class variable(3) {test.f}')

언급URL : https://stackoverflow.com/questions/1537202/difference-between-variables-inside-and-outside-of-init-class-and-instanc

반응형