Namespace

좁은의미 …

  • 파이썬에서 어떤 부분(스코프)에서 코드(할당문)가 작성되느냐에 따라 객체를 가리키는 식별자(변수명)와 객체는 다른 공간에 속하게 된다.
  • 이와같은 식별자와 객체가 속하는 서로다른 공간을 Namespace(이름공간)이라고 한다.
  • 모듈에서 코드가 작성되면 모듈이 가지는 네임스페이스인 전역네임스페이스에 식별자와 객체가 생성되며 매핑되는 관계를 가지게 된다.
  • 함수안에서 코드가 작성되면 함수의 네임스페이스인 지역네임스페이스에서 식별자와 객체가 생성되며 서로 매핑되는 관계를 가지며 클래스,인스턴스에서도 네임스페이스라는 개념이 존재한다.
  • 이 매핑관계는 파이썬에서 딕셔너리로 구현된다.

더 넓은의미 ….

  • 네임스페이스는 단순히 식별자와 객체가 소속되는 공간이라는 의미를 넘어서서 나아가 코드의 실행이 이루어지는 공간을 의미하기도 한다.

동작요약

객체에 대해 뭔가 실행 -> 네임스페이스에서 객체를 조회 -> 객체를 가져옴(없거나 다른 네임스페이스에도 없으면 에러)
지역네임스페이스에 없으면 -> 전역네임스페이스 조회,여기에도 없으면 -> 빌트인 네임스페이스 조회,여기에도 없으면 오류

스코프 : 코드상의 어떤 영역을 말한다. 하나 또는 여러개의 네임스페이스와 네임스페이스와 연결되어 있다.

참고링크
https://post.naver.com/viewer/postView.nhn?volumeNo=27785662&memberNo=21815&navigationType=push
https://schoolofweb.net/blog/posts/%ED%8C%8C%EC%9D%B4%EC%8D%AC-oop-part-3-%ED%81%B4%EB%9E%98%EC%8A%A4-%EB%B3%80%EC%88%98class-variable/
https://wikidocs.net/1743
https://hcnoh.github.io/2021-04-17-dkvmn

모듈의 전역네임스페이스 살펴보기

a=10;b=20
#전역네임스페이스를 보여주는 명령어
#전역네임스페이스에 존재하는 식별자와 객체들을 볼 수 있다.
globals()
{'__name__': '__main__',
 '__doc__': 'Automatically created module for IPython interactive environment',
 '__package__': None,
 '__loader__': None,
 '__spec__': None,
 '__builtin__': <module 'builtins' (built-in)>,
 '__builtins__': <module 'builtins' (built-in)>,
 '_ih': ['',
  'a=10;b=20',
  '#전역네임스페이스를 보여주는 명령어\n#전역네임스페이스에 존재하는 식별자와 객체들을 볼 수 있다.\nglobals()'],
 '_oh': {},
 '_dh': ['/content'],
 'In': ['',
  'a=10;b=20',
  '#전역네임스페이스를 보여주는 명령어\n#전역네임스페이스에 존재하는 식별자와 객체들을 볼 수 있다.\nglobals()'],
 'Out': {},
 'get_ipython': <bound method InteractiveShell.get_ipython of <google.colab._shell.Shell object at 0x7fe22c68e490>>,
 'exit': <IPython.core.autocall.ZMQExitAutocall at 0x7fe229652590>,
 'quit': <IPython.core.autocall.ZMQExitAutocall at 0x7fe229652590>,
 '_': '',
 '__': '',
 '___': '',
 '_i': 'a=10;b=20',
 '_ii': '',
 '_iii': '',
 '_i1': 'a=10;b=20',
 'a': 10,
 'b': 20,
 '_i2': '#전역네임스페이스를 보여주는 명령어\n#전역네임스페이스에 존재하는 식별자와 객체들을 볼 수 있다.\nglobals()'}
#지역네임스페이스를 보여주는 명령어
#지역네임스페이스는 어떤 스코프에서의 네임스페이스를 보여준다.
#모듈의 지역네임스페이스는 전역네임스페이스와 같으므로 두 결과는 서로 같다.
locals()
{'__name__': '__main__',
 '__doc__': 'Automatically created module for IPython interactive environment',
 '__package__': None,
 '__loader__': None,
 '__spec__': None,
 '__builtin__': <module 'builtins' (built-in)>,
 '__builtins__': <module 'builtins' (built-in)>,
 '_ih': ['',
  'a=10;b=20',
  '#전역네임스페이스를 보여주는 명령어\n#전역네임스페이스에 존재하는 식별자와 객체들을 볼 수 있다.\nglobals()',
  '#지역네임스페이스를 보여주는 명령어\n#지역네임스페이스는 어떤 스코프에서의 네임스페이스를 보여준다.\n#모듈의 지역네임스페이스는 전역네임스페이스와 같으므로 두 결과는 서로 같다.\nlocals()'],
 '_oh': {2: {...}},
 '_dh': ['/content'],
 'In': ['',
  'a=10;b=20',
  '#전역네임스페이스를 보여주는 명령어\n#전역네임스페이스에 존재하는 식별자와 객체들을 볼 수 있다.\nglobals()',
  '#지역네임스페이스를 보여주는 명령어\n#지역네임스페이스는 어떤 스코프에서의 네임스페이스를 보여준다.\n#모듈의 지역네임스페이스는 전역네임스페이스와 같으므로 두 결과는 서로 같다.\nlocals()'],
 'Out': {2: {...}},
 'get_ipython': <bound method InteractiveShell.get_ipython of <google.colab._shell.Shell object at 0x7fe22c68e490>>,
 'exit': <IPython.core.autocall.ZMQExitAutocall at 0x7fe229652590>,
 'quit': <IPython.core.autocall.ZMQExitAutocall at 0x7fe229652590>,
 '_': {...},
 '__': '',
 '___': '',
 '_i': '#전역네임스페이스를 보여주는 명령어\n#전역네임스페이스에 존재하는 식별자와 객체들을 볼 수 있다.\nglobals()',
 '_ii': 'a=10;b=20',
 '_iii': '',
 '_i1': 'a=10;b=20',
 'a': 10,
 'b': 20,
 '_i2': '#전역네임스페이스를 보여주는 명령어\n#전역네임스페이스에 존재하는 식별자와 객체들을 볼 수 있다.\nglobals()',
 '_2': {...},
 '_i3': '#지역네임스페이스를 보여주는 명령어\n#지역네임스페이스는 어떤 스코프에서의 네임스페이스를 보여준다.\n#모듈의 지역네임스페이스는 전역네임스페이스와 같으므로 두 결과는 서로 같다.\nlocals()'}

함수의 지역네임스페이스 확인해보기

def printhi():
  text = "hi"
  text2 = "hello"
  print("hi")
  print(__name__)
  print(locals())
printhi()
hi
__main__
{'text': 'hi', 'text2': 'hello'}
globals()
{'__name__': '__main__',
 '__doc__': 'Automatically created module for IPython interactive environment',
 '__package__': None,
 '__loader__': None,
 '__spec__': None,
 '__builtin__': <module 'builtins' (built-in)>,
 '__builtins__': <module 'builtins' (built-in)>,
 '_ih': ['',
  'a=10;b=20',
  '#전역네임스페이스를 보여주는 명령어\n#전역네임스페이스에 존재하는 식별자와 객체들을 볼 수 있다.\nglobals()',
  '#지역네임스페이스를 보여주는 명령어\n#지역네임스페이스는 어떤 스코프에서의 네임스페이스를 보여준다.\n#모듈의 지역네임스페이스는 전역네임스페이스와 같으므로 두 결과는 서로 같다.\nlocals()',
  'def printhi():\n  text = "hi"\n  text2 = "hello"\n  print("hi")\n  print(__name__)\n  print(locals())\nprinthi()',
  'globals()'],
 '_oh': {2: {...}, 3: {...}},
 '_dh': ['/content'],
 'In': ['',
  'a=10;b=20',
  '#전역네임스페이스를 보여주는 명령어\n#전역네임스페이스에 존재하는 식별자와 객체들을 볼 수 있다.\nglobals()',
  '#지역네임스페이스를 보여주는 명령어\n#지역네임스페이스는 어떤 스코프에서의 네임스페이스를 보여준다.\n#모듈의 지역네임스페이스는 전역네임스페이스와 같으므로 두 결과는 서로 같다.\nlocals()',
  'def printhi():\n  text = "hi"\n  text2 = "hello"\n  print("hi")\n  print(__name__)\n  print(locals())\nprinthi()',
  'globals()'],
 'Out': {2: {...}, 3: {...}},
 'get_ipython': <bound method InteractiveShell.get_ipython of <google.colab._shell.Shell object at 0x7fe22c68e490>>,
 'exit': <IPython.core.autocall.ZMQExitAutocall at 0x7fe229652590>,
 'quit': <IPython.core.autocall.ZMQExitAutocall at 0x7fe229652590>,
 '_': {...},
 '__': {...},
 '___': '',
 '_i': 'def printhi():\n  text = "hi"\n  text2 = "hello"\n  print("hi")\n  print(__name__)\n  print(locals())\nprinthi()',
 '_ii': '#지역네임스페이스를 보여주는 명령어\n#지역네임스페이스는 어떤 스코프에서의 네임스페이스를 보여준다.\n#모듈의 지역네임스페이스는 전역네임스페이스와 같으므로 두 결과는 서로 같다.\nlocals()',
 '_iii': '#전역네임스페이스를 보여주는 명령어\n#전역네임스페이스에 존재하는 식별자와 객체들을 볼 수 있다.\nglobals()',
 '_i1': 'a=10;b=20',
 'a': 10,
 'b': 20,
 '_i2': '#전역네임스페이스를 보여주는 명령어\n#전역네임스페이스에 존재하는 식별자와 객체들을 볼 수 있다.\nglobals()',
 '_2': {...},
 '_i3': '#지역네임스페이스를 보여주는 명령어\n#지역네임스페이스는 어떤 스코프에서의 네임스페이스를 보여준다.\n#모듈의 지역네임스페이스는 전역네임스페이스와 같으므로 두 결과는 서로 같다.\nlocals()',
 '_3': {...},
 '_i4': 'def printhi():\n  text = "hi"\n  text2 = "hello"\n  print("hi")\n  print(__name__)\n  print(locals())\nprinthi()',
 'printhi': <function __main__.printhi()>,
 '_i5': 'globals()'}

LGB RULE

  • 파이썬 인터프리터는 해당네임스페이스에 식별자를 통해서 찾는 객체가 없으면 그 상위 네임스페이스에서 식별자를 통해 객체를 참조하게 된다. 만약 상위 네임스페이스에도 찾을 수 없는 경우 에러를 띄우게 된다.
  • 따라서 아래와 같은 경우는 에러를 띄우지 않는다.
x = 1
def no_local():
    print(locals())
    print(x)
no_local()
{}
1

CLASS,instance와 LCGB RULE

  • 파이썬에서는 클래스도 하나의 함수 객체의 성격을 가진다.
  • 그래서 클래스 내부에서 변수가 선언되면 객체는 식별자와 객체는 클래스 내부의 지역네임스페이스에 속하게 된다.

추가적으로 .. - 클래스 함수는 그 반환값이 사용자가 정의한 객체이다.

CLASS

class Resnet(): #클래스 함수를 정의하는 경우 def대신 class를 입력한다.
  temp = 25
  #print(locals())
# 이 코드를 실행하면 c는 Resnet이라는 클래스 함수의 호출을 통해 생성된 객체의 식별자가 된다.
# 클래스 함수는 그 반환값이 사용자가 정의한 객체가 되며 이 객체를 변수c가 가리키게 된다.
Resnet.__dict__ #클래스의 네임스페이스 확인
#클래스에 print(locals())로도 확인할 수 있음.
mappingproxy({'__module__': '__main__',
              'temp': 25,
              '__dict__': <attribute '__dict__' of 'Resnet' objects>,
              '__weakref__': <attribute '__weakref__' of 'Resnet' objects>,
              '__doc__': None})
globals() #전역네임스페이스에 클래스 Resnet이 추가된 것도 확인
{'__name__': '__main__',
 '__doc__': 'Automatically created module for IPython interactive environment',
 '__package__': None,
 '__loader__': None,
 '__spec__': None,
 '__builtin__': <module 'builtins' (built-in)>,
 '__builtins__': <module 'builtins' (built-in)>,
 '_ih': ['',
  'a=10;b=20',
  '#전역네임스페이스를 보여주는 명령어\n#전역네임스페이스에 존재하는 식별자와 객체들을 볼 수 있다.\nglobals()',
  '#지역네임스페이스를 보여주는 명령어\n#지역네임스페이스는 어떤 스코프에서의 네임스페이스를 보여준다.\n#모듈의 지역네임스페이스는 전역네임스페이스와 같으므로 두 결과는 서로 같다.\nlocals()',
  'def printhi():\n  text = "hi"\n  text2 = "hello"\n  print("hi")\n  print(__name__)\n  print(locals())\nprinthi()',
  'globals()',
  'x = 1\ndef no_local():\n    print(locals())\n    print(x)\nno_local()',
  'class Resnet(): #클래스 함수를 정의하는 경우 def대신 class를 입력한다.\n  temp = 25\n  #print(locals())\n# 이 코드를 실행하면 c는 Resnet이라는 클래스 함수의 호출을 통해 생성된 객체의 식별자가 된다.\n# 클래스 함수는 그 반환값이 사용자가 정의한 객체가 되며 이 객체를 변수c가 가리키게 된다.',
  'Resnet.__dict__ #클래스의 네임스페이스 확인\n#클래스에 print(locals())로도 확인할 수 있음.',
  'globals() #전역네임스페이스에 클래스 Resnet이 추가된 것도 확인'],
 '_oh': {2: {...},
  3: {...},
  5: {...},
  8: mappingproxy({'__module__': '__main__',
                'temp': 25,
                '__dict__': <attribute '__dict__' of 'Resnet' objects>,
                '__weakref__': <attribute '__weakref__' of 'Resnet' objects>,
                '__doc__': None})},
 '_dh': ['/content'],
 'In': ['',
  'a=10;b=20',
  '#전역네임스페이스를 보여주는 명령어\n#전역네임스페이스에 존재하는 식별자와 객체들을 볼 수 있다.\nglobals()',
  '#지역네임스페이스를 보여주는 명령어\n#지역네임스페이스는 어떤 스코프에서의 네임스페이스를 보여준다.\n#모듈의 지역네임스페이스는 전역네임스페이스와 같으므로 두 결과는 서로 같다.\nlocals()',
  'def printhi():\n  text = "hi"\n  text2 = "hello"\n  print("hi")\n  print(__name__)\n  print(locals())\nprinthi()',
  'globals()',
  'x = 1\ndef no_local():\n    print(locals())\n    print(x)\nno_local()',
  'class Resnet(): #클래스 함수를 정의하는 경우 def대신 class를 입력한다.\n  temp = 25\n  #print(locals())\n# 이 코드를 실행하면 c는 Resnet이라는 클래스 함수의 호출을 통해 생성된 객체의 식별자가 된다.\n# 클래스 함수는 그 반환값이 사용자가 정의한 객체가 되며 이 객체를 변수c가 가리키게 된다.',
  'Resnet.__dict__ #클래스의 네임스페이스 확인\n#클래스에 print(locals())로도 확인할 수 있음.',
  'globals() #전역네임스페이스에 클래스 Resnet이 추가된 것도 확인'],
 'Out': {2: {...},
  3: {...},
  5: {...},
  8: mappingproxy({'__module__': '__main__',
                'temp': 25,
                '__dict__': <attribute '__dict__' of 'Resnet' objects>,
                '__weakref__': <attribute '__weakref__' of 'Resnet' objects>,
                '__doc__': None})},
 'get_ipython': <bound method InteractiveShell.get_ipython of <google.colab._shell.Shell object at 0x7fe22c68e490>>,
 'exit': <IPython.core.autocall.ZMQExitAutocall at 0x7fe229652590>,
 'quit': <IPython.core.autocall.ZMQExitAutocall at 0x7fe229652590>,
 '_': mappingproxy({'__module__': '__main__',
               'temp': 25,
               '__dict__': <attribute '__dict__' of 'Resnet' objects>,
               '__weakref__': <attribute '__weakref__' of 'Resnet' objects>,
               '__doc__': None}),
 '__': {...},
 '___': {...},
 '_i': 'Resnet.__dict__ #클래스의 네임스페이스 확인\n#클래스에 print(locals())로도 확인할 수 있음.',
 '_ii': 'class Resnet(): #클래스 함수를 정의하는 경우 def대신 class를 입력한다.\n  temp = 25\n  #print(locals())\n# 이 코드를 실행하면 c는 Resnet이라는 클래스 함수의 호출을 통해 생성된 객체의 식별자가 된다.\n# 클래스 함수는 그 반환값이 사용자가 정의한 객체가 되며 이 객체를 변수c가 가리키게 된다.',
 '_iii': 'x = 1\ndef no_local():\n    print(locals())\n    print(x)\nno_local()',
 '_i1': 'a=10;b=20',
 'a': 10,
 'b': 20,
 '_i2': '#전역네임스페이스를 보여주는 명령어\n#전역네임스페이스에 존재하는 식별자와 객체들을 볼 수 있다.\nglobals()',
 '_2': {...},
 '_i3': '#지역네임스페이스를 보여주는 명령어\n#지역네임스페이스는 어떤 스코프에서의 네임스페이스를 보여준다.\n#모듈의 지역네임스페이스는 전역네임스페이스와 같으므로 두 결과는 서로 같다.\nlocals()',
 '_3': {...},
 '_i4': 'def printhi():\n  text = "hi"\n  text2 = "hello"\n  print("hi")\n  print(__name__)\n  print(locals())\nprinthi()',
 'printhi': <function __main__.printhi()>,
 '_i5': 'globals()',
 '_5': {...},
 '_i6': 'x = 1\ndef no_local():\n    print(locals())\n    print(x)\nno_local()',
 'x': 1,
 'no_local': <function __main__.no_local()>,
 '_i7': 'class Resnet(): #클래스 함수를 정의하는 경우 def대신 class를 입력한다.\n  temp = 25\n  #print(locals())\n# 이 코드를 실행하면 c는 Resnet이라는 클래스 함수의 호출을 통해 생성된 객체의 식별자가 된다.\n# 클래스 함수는 그 반환값이 사용자가 정의한 객체가 되며 이 객체를 변수c가 가리키게 된다.',
 'Resnet': __main__.Resnet,
 '_i8': 'Resnet.__dict__ #클래스의 네임스페이스 확인\n#클래스에 print(locals())로도 확인할 수 있음.',
 '_8': mappingproxy({'__module__': '__main__',
               'temp': 25,
               '__dict__': <attribute '__dict__' of 'Resnet' objects>,
               '__weakref__': <attribute '__weakref__' of 'Resnet' objects>,
               '__doc__': None}),
 '_i9': 'globals() #전역네임스페이스에 클래스 Resnet이 추가된 것도 확인'}
  • def로 정의하는 함수객체와는 달리 class로 정의한 클래스 함수 객체와 이 클래스의 네임스페이스에 속한 객체들을 “.”이라는 기호를 통해 접근할 수 있음.
  • 위와 같이 클래스안에서 25라는 객체와 바인딩된 temp를 클래스변수라하며 식별자와 객체는 별도의 클래스(라는 또하나의 다른 함수)네임스페이스에 속하게 된다.

instance

  • 클래스라는 함수를 호출하면 객체를 반환함.
  • 이 반환된 객체를 인스턴스라 하며 인스턴스는 클래스가 별도로 클래스의 네임스페이스를 가진것처럼 인스턴스도 별도로 인스턴스의 네임스페이스를 가짐.
r1 = Resnet() #클래스 호출하여 인스턴스 생성
r2 = Resnet()
print(id(r1),id(r2))
#메모리상에 다른 주소에서 저장됨을 확인
140609160422160 140609160422416
dir() #전역네임스페이스에 r1,r2가 추가적으로 있음을 확인
['In',
 'Out',
 'Resnet',
 '_',
 '_2',
 '_3',
 '_5',
 '_8',
 '_9',
 '__',
 '___',
 '__builtin__',
 '__builtins__',
 '__doc__',
 '__loader__',
 '__name__',
 '__package__',
 '__spec__',
 '_dh',
 '_i',
 '_i1',
 '_i10',
 '_i11',
 '_i2',
 '_i3',
 '_i4',
 '_i5',
 '_i6',
 '_i7',
 '_i8',
 '_i9',
 '_ih',
 '_ii',
 '_iii',
 '_oh',
 'a',
 'b',
 'exit',
 'get_ipython',
 'no_local',
 'printhi',
 'quit',
 'r1',
 'r2',
 'x']
r1.__dict__ #인스턴스의 네임스페이스 확인
#아무것도 없음을 확인할 수 있음
{}
r2.__dict__
{}

클래스 함수를 호출하여 인스턴스(객체)의 네임스페이스에 새로운 식별자와 객체가 속하게 하려면 init(self)와 self.변수명 을 작성하면 됨.

class Resnet():
  temp = 25
  def __init__(self):
    self.v1 = [1,2,3,4]
    self.s1 = "hi"
  #print(locals())
r1 = Resnet()
r2 = Resnet()
r1.__dict__ #객체(인스턴스)의 네임스페이스에 새로운 식별자와 변수들의 매핑관계가 있음을 확인할 수 있음.
{'v1': [1, 2, 3, 4], 's1': 'hi'}
r2.__dict__
{'v1': [1, 2, 3, 4], 's1': 'hi'}
#클래스의 네임스페이스에 "."이라는 기호로 접근할 수 있음
print(Resnet.temp)
print(id(Resnet.temp))

#인스턴스의 네임스페이스에 "."이라는 기호로 접근가능
c = Resnet()
print(c.temp)
print(id(c.temp))

#메모리상에서 같은 주소에 저장되어 있음도 확인
25
11127456
25
11127456

LCGB RULE

  • 새로 생성된 객체의 내부 지역네임스페이스 즉 인스턴스의네임스페이스에 없는 객체를 가져오라 명령=> 클래스의 네임스페이스를 조회하고 그래도 없으면 상위 네임스페이스를 조회하게 된다.
class Resnet_2():
  z=2
  def __init__(self):
    temp = 2
    temp = "hi"
    #print(locals())
resnet = Resnet_2()
print(resnet.__dict__,resnet.z)
#resnet이라는 인스턴스(객체)의 네임스페이스에 z라는 변수가 없음
#근데 z라는 변수가 가리키는 객체를 가져오라고 명령 -> 클래스의 네임스페이스를 조회하고 
#그래도 없으면 더 상위의네임스페이스를 조회
{} 2
class Resnet_2():
  z=2
  def __init__(self):
    temp = 2
    temp = "hi"
    self.z = 32
resnet = Resnet_2()
print(resnet.__dict__,resnet.z)
#이 경우는 인스턴스의 네임스페이스에 식별자와 객체가 있으므로 클래스네임스페이스를 조회하지 않음.
{'z': 32} 32

#self에 대한 고찰 결론
1. self는 태몽? 같은 느낌이다. 즉,클래스에 대해서 코드를 작성할때에는 만들지 않았지만 … 미래에 클래스를 호출하여 객체를 만들면 어떤 객체가 메모리상의 어떤 공간에 있을텐데 그 객체를 가리키며 객체와 바인딩되는 변수라고 생각하면 된다.
예를들어서, cookie = Cookie()이렇게 하면 cookie라는 변수는 Cookie객체와 바인딩된다. self도 이와같이 Cookie객체와 바인딩되는데 이제 클래스를 코드로 작성할때에는 미리만들어질 객체에 지칭을 해주기 위해서 이런 이름이 붙었다고 생각하면 될 것 같다. 2. “.”을 사용하여 객체와 변수사이에 .을 붙이면 즉,객체.변수 하면 객체의 네임스페이스안에 있는 또다른 객체들에 접근할 수 있다..(정확히는 객체(인스턴스)와바인딩된변수.객체(인스턴스)의 네임스페이스에 속한 변수명(식별자)라고 할 수 있다.)클래스를 작성할때 메소드안에 이 self를 적는 이유는 클래스로부터 만들어진 인스턴스의 네임스페이스안에 있는 객체에 대해서 접근하여 뭔가를 바꾸거나 조작하기 위해서이다. 3. 인스턴스.메서드()를 하면 함수에 아무인자를 넣어주지않았지만 파이썬스스로 객체(인스턴스)그 자체를 첫번째 인자로 전달해준다.이는 클래스.메소드(인스턴스)라는 코드와 완전히 동일하다. 4. 만약에 인스턴스(객체)의 메소드를 실행시키지 않고 클래스의 자체에서 메소드를 실행시키는 경우,self는 필요가 없다.

핵심요약 1. self는 객체 또는 인스턴스 그 자체를 가리키는 변수. 2. 객체(인스턴스)의 네임스페이스에 속한 또다른 객체들은 객체(인스턴스)와 바인딩된 변수.객체와 바인딩된변수라는 방식으로 접근 가능.간단히 인스턴스.멤버변수로 접근가능 3. 1,2에 의하여, self라는 객체와 바인딩된 변수를 메소드의 인자로 받으면 self.멤버변수 이런식으로 인스턴스의 변수에 접근 가능함.

인스턴스의 가용범위 : https://andamiro25.tistory.com/38

class cookie():
  given = "cookie" #클래스변수 cookie선언 
  maked_num = 0 #클래스변수 선언,모든 인스턴스에 대해서 공통된 연산이 되어야 할 때 할당.
  def __init__(self,flavor,size):
    self.flavor = flavor
    self.size = size
    print("메모리 주소 :",id(self))
  def sizeup(self): #self를 왜쓸까? => self는 객체(인스턴스)그 자체이므로 self.~~로 네임스페이스에 있는 객체에 접근 가능함.인스턴스의 네임스페이스에 있는 객체에 뭔가를 추가하거나 조작하거나 해야하는 메서드는 self를 사용함
    self.size +=5
cookie1 = cookie("banana",25)
cookie2 = cookie("melon",10)
print("쿠키1",id(cookie1))
print("쿠키2",id(cookie2))
#self라는 객체의 메모리주소를 가리켜보니 변수cookie1,cookie2가 가리키는 객체의 메모리주소와 같다
#즉,self는 객체(인스턴스) 그 자체를 가리킨다!
메모리 주소 : 140609086555024
메모리 주소 : 140609086554896
쿠키1 140609086555024
쿠키2 140609086554896
print(cookie1.maked_num,cookie1.flavor,cookie1.size)
print(cookie2.maked_num,cookie2.flavor,cookie2.size)
0 banana 25
0 melon 10
cookie1.__dict__,cookie2.__dict__ #cookie1,cookie2라는 객체(인스턴스)의 네임스페이스 확인
#서로다른 독립적인 네임스페이스를 가지는 것을 확인
({'flavor': 'banana', 'size': 25}, {'flavor': 'melon', 'size': 10})
cookie.sizeup(cookie1);print(cookie1.size)
#==cookie1.sizeup()
30
class cookie_inform():
  #클래스 변수 선언
  making_time = "1345"
  price =2000
  maked_num = 0
  def making_up(maked_num):
    maked_num+=1
cookie_inform.making_up(cookie_inform.maked_num)
cookie_inform.maked_num
0
cookie1.__dict__
{'flavor': 'banana', 'size': 25, 'd': 'hi'}