.으로 접근할 수 있는 딕셔너리

```python

class dotdict(dict):

    def __getattr__(self, name):

        return self[name]

```


클래스 메서드에서 어떤 값을 초기 한 번만 계산하고 이후 호출에서는 단순히 반환만 하고 싶을 때

```python
class T:
    def getData(self):
        if hasattr(self, "var"):
            self.var = 3
        return self.var
```

2019/02/04 - [Coding Syntax/Python] - 파이썬에는 확장 함수가 없다. 어떤 클래스에 추가 기능이 필요한 경우.


파이썬에서 클로저 사용하기

```python
def makeMultiplier(operand):
    def multiplier(arg):
        return arg * operand

    return multiplier
```
```python
>>> multi2 = makeMultiplier(2)
>>> multi2(4)
8
```

@dump 데커레이터

dump 데커레이터

```python

def dump(func):

    def wrapped(*args, **kwargs):

        print("func name: {}".format(func.__name__))

        print("args     : {}".format(' '.join(map(str, args))))

        print("kwargs   : {}".format(kwargs.items()))

        output = func(*args, **kwargs)

        print("output   : {}".format(output))

        return output

    return wrapped

```

vars() 키워드

```python

>>> def a(a):

...     print(vars())

...

>>> a(3)

{'a': 3}

```



전역 변수, 모듈 스코프 변수 보다는 class level 변수를 사용하자.


main.py

```python

from g_val import *

print("1 ", a)

print(id(a))

a = False

delay()

print("3 ", a)

print(id(a))

```

g_val.py

```python

import time

a = True

def delay():

    print("2 ", a)

    print(id(a))

```

```python

λ python main.py

1  main  True

140734249552208

2  g_val True    # False로 변경되어야 할 것 같지만, 그렇지 않다.

140734249552208

3  main  False

140734249552240

```

처음에는 main.py에서 a라는 변수에 접근할 때는, g_val에서 불러온 변수 그대로다.

그러나 main.py에서 a = 어쩌구로 할당 하는 순간 새로운 변수가 잡혀버린다.

때문에 main.py에서 a = False로 변경한 값이 반영되지 않았다.


* 객체나 배열이라면 이런식으로 할당할일이 없으므로 재할당하면서 새로운 변수가 잡히는 케이스가 드물기는 하다.


그러나 import를 다음과 같이 하면...

main.py

```python

import g_val as g

print("1 ", g.a)

print(id(g.a))

g.a = False

g.delay()

print("3 ", g.a)

```

```python

λ python main.py

1  main  True

140734249552240

2  g_val False

140734249552240

3  main  False

140734249552240

```

이렇게 하면 a라는 변수에 새로운 값을 대입하더라도 a가 새로 할당되는 것이 아니고, a라는 변수가 각 모듈 간 공유된다.


``py global a``를 적어주어도 차이가 없다. 위와 같은 결과다. 


그래서 파이썬에서 모듈 간 공유해야 하는 변수가 있다면, 모듈 스코프 변수나 전역 변수를 사용하기 보다는

class 레벨에서 class variable로 선언하는 것이 좋아 보인다.

아니면 import g_val as g 처럼 특정한 import 규칙을 정하거나. (이런 특정한 규칙은 팀 멤버들이 모두 공유해야 한다는 번거로움이 생긴다.)



어떤 클래스에 추가 기능이 필요한 경우, 파이썬에서는 

1. backing property를 이용한 operator overloading

2. 상속받아서 추가 기능 구현

두 가지 방법을 생각할 수 있다.

코틀린과 같은 언어는 여기서 확장 함수를 사용하는 방법도 생각해 볼 수 있지만, 파이썬은 이를 지원하지 않는다.

```python

import numpy as np


# sol 1.

class OperatorOverloading:

    def __init__(self):

        self.board = np.zeros((8, 8), dtype=int)


    def __getitem__(self, point):

        i, j = point

        return self.board[i][j]


    def myFunc(self):

        return "my function!"


A = OperatorOverloading()

print(A[1,2])

print(A.myFunc())


# sol 2.

class Extern(np.ndarray):

    """

    https://docs.scipy.org/doc/numpy/user/basics.subclassing.html

    type casting하는 방식 말고, 좀 더 복잡하지만 __new__ 등을 overloading해서 완전 서브클래스로 사용하는 방법도 있다.

    """

    def myFunc(self):

        return "my function!"


_B = np.zeros((8, 8), dtype=int)

B = _B.view(Extern)

print(B[1][2])

print(B.myFunc())


# 확장 함수는 지원하지 않음.

C = np.zeros((8, 8), dtype=int)

C.myFunc = lambda x: "my function!"

print(C.myFunc())    # AttributeError: 'numpy.ndarray' object has no attribute 'myFunc'

```


+ Recent posts

티스토리 툴바