# [Python] 파이썬 기초

## 파이썬

---

![Image](https://upload.cafenono.com/image/slashpagePost/20250107/162337_r7NZro6UBndIm2BNgg?q=80&s=1280x180&t=outside&f=webp)

**파이썬 Python**

- 1990년 암스테르담의 귀도 반 로섬이 개발한 **인터프리터 언어**

- 소스 코드를 한 줄씩 해석한 후 실행한 결과를 바로 확인 가능

- 공동 작업과 유지 보수가 매우 쉽고 편리하다

**파이썬의 특징**

- 파이썬은 인간 다운 언어

- 문법이 쉬워 빠르게 배울 수 있다

- 무료이지만 강력하다

- 간결하다

- 프로그래밍을 즐기게 해준다

- 개발 속도가 빠르다

## 함수형 프로그래밍

---

**함수형, 절차형, 객체지향**

- 프로그래밍 언어는 여러 가지 프로그래밍 패러다임을 지원

- 프로그래머가 문제를 이해하고 해결하는 방법에 영향을 미친다

### **함수형 프로그래밍**

- 계산을 일련의 함수 호출로 표현

- 순수 함수(외부 변수를 참조하여 값을 생성하지 않음)와 불변성(list를 argument로 받아서 안의 값을 변경하지 않음)을 중점이 둔다

- 결과가 입력에만 의존하고 프로그램의 상태를 변경하지 않아야 함을 의미

- 코딩을 함으로 사이드 이펙트(의도하지 않은 결과)를 방지할 수 있다

- 장점: 예측성, 안정성과 테스트 용이성

- 단점: 함수형 프로그래밍 언어를 이해하는 것이 어렵다

### 객체지향 프로그래밍

**절차형 프로그래밍**

- 프로그래밍을 일련의 절차 또는 단계로 묘사하는 패러다임

- 코들르 재사용, 구조화하는 데 유용, 대부분의 프로글밍 언어가 절차형 프로그래밍 언어

- 프로그램의 상태를 추적하는데 복잡 → 버그의 원인이 될 수 있다

**객체지향 프로그래밍**

- 파이썬은 객체지향 프로그래밍 언어

- 객체가 중심, 참조 변수를 통해 객체에 접근 가능

- C언어는 변수가 생성되고 변수에 값이 저장되는 구조

- 파이썬의 변수는 동적으로 참조하는 객체가 지정된다

- 장점: 코드의 재사용성 높임, 코드의 구조 개선으로 복잡성 관리에 유용

- 단점: 초기 학습 곡선이 가파르고, 잘못 사용하면 코드 복잡성 높아짐

### Python 주요 업데이트

---

**Python 3.5**

- `async`와 `await` : `async def`를 사용하여 코루틴 정의, await를 사용하여 코루틴이 완료될 때까지 대기 가능

**Python 3.6**

- **f-string**: 문자열 내부에 중괄호`{}`를 사용하여 변수를 직접 삽입 가능

```javascript
name = "Alice"
print(f"Hello, {name}")
```

- 변수 타입 힌트: 반환 값에 대한 타입 정보 제공 → 오류를 더 잘 잡아낼 수 있음

```javascript
def great(name: str) -> str:
    return f"Hello, {name}"
```

**Python 3.7**

- `dataclasses`: `@dataclass` 데코레이터를 제공하여 클래스를 간결하게 정의

    - `__init__`, `__repr__`, `__eq__` 등의 특별한 메서드를 자동으로 추가

```javascript
# id, name, emial이 각각 3번씩 반복
# 이러한 현상을 보일러 플레이트(boiler-plate)라고 함
# print를 해도 필드 값이 보이지 않아 불편

class User:
    def __init__(self, id, name, email):
        self.id = id
        self.name = name
        self.email = email
```

```javascript
# id, name, emial이 각각 3번씩 반복
# 이러한 현상을 보일러 플레이트(boiler-plate)라고 함
# print를 해도 필드 값이 보이지 않아 불편

class User:
    def __init__(self, id, name, email):
        self.id = id
        self.name = name
        self.email = email
    
    def __repr__(self):
        return (f'{self.__class__.__qualname__}{self.id, self.name, self.email}')
    
user = User(123,'hojun', 'hojun@gmail')
user
```

```javascript
from dataclasses import dataclass

@dataclass
class User:
    id: int
    name: str
    email: str

user = User(123,'hojun', 'hojun@gmail')
user
```

**Python 3.8**

- **왈러스 연산자** `:=`: 표현식을 평가하고 그 결과를 변수에 할당

- **왈러스 연산자**

    - Python 3.8에서 도입

    - 할당 표현식을 사용하게 해주는 연산자

    - “이름을 표현식의 결과에 연결”하거나 “값을 이름에 할당하면서 그 값을 평가”

    - 표현식을 계산하면서 동시에 그 결과를 변수에 할당할 수 있음

```javascript
# 기본적인 왈러스 연산자의 사용
x = (n := 10) * 2 # 10을 n에 할당, 그 값을 반환
print(x) # 출력: 20
print(n) # 출력: 10
```

```javascript
# 왈라스 연산자가 없을 때의 코드
import random

while True:
    x = random.randint(0, 10)
    if x == 7:
        break
    print(x)

# 왈라스 연산자를 사용한 코드
import random

while(x := random.randint(0, 10)) != 7:
    print(x)
```

```javascript
def sigma(n):
    count = 0
    result = 0
    while(count := count+ 1) < n + 1:
        result += count
    return result

if(sum := sigma(100)) ** 5050:
    print('5050이 출력되었습니다.')
else:
    print('1부터 정수형태로 입력이 가능합니다.')
print(sum * 1000)
```

  **왈러스 연산자 주의사항**

    - 할당 연산자 `*`와 비슷하지만, 활용 범위와 용도가 다르므로 사용에 주의해야한다

    - 코드의 가독성을 위해 복잡한 표현식 내에서 알러스 연산자의 남용을 피해야한다

    - 복잡한 한 줄 코드 보다는 여러 줄에 걸친 명확한 코드가 유지보수와 이해에 더 좋을 수 있다

    - 연산자를 통해 코드의 효율성과 가독성을 높일 수 있다. 그러나 남용하면 코드의 가독성을 오히려 떨어뜨릴 수 있으므로 적절한 균형이 중

**Python 3.9**

- 딕셔너리 결합 연산자: 딕셔너리 병합, 업데이트를 위해 `|`와 `|=` 연산자가 추가됨

```javascript
# 딕셔너리 언패킹 -> 3.5 버전
x = {"key1": "value1"}
y = {"key2": "value2"}
z = {**x, **y}
z
```

```javascript
# 딕셔너리 병합 -> 3.9 버전
x = {"key1": "value1"}
y = {"key2": "value2"}
z = x | y
z
```

## 독스트링, 컨벤션에 주석

---

- Python에서 독스트링 document string은 함수, 클래스, 모듈 등의 주석을 작성하는 표준 방법

- 따옴표로 둘러싸인 문자열, 정의된 항목을 바로 아래에 나타나야 한다

- Python 공식 스타일 가이드 PEP 257인 독스트링 작성을 위한 일반적인 가이드라인 제시

- 회사나 팀별 세분화하거나 구체화한 자체 컨벤션을 가지고 있을 수 있다

**가장 많이 사용하는 Google Conventions**

-   [[Google Coding 컨벤션] #1 Python 코딩 컨벤션](https://www.youtube.com/watch?v=5lr9Z9oqoYk)

-   [Python google coding conventions](https://www.notion.so/Python-google-coding-conventions-58cd70abfef04c90b717aa59c7522280?pvs=21) 

**PEP 257에서 제시하는 일반적인 작성 가이드라인**

1. **일반적인 형식**: 독스트링은 하앙 삼중 따옴표를 사용해 작성

2. **한줄 독스트링**: 닫는 따옴표는 같은 줄에 위치

```javascript
def add(a, b):
    """Add two numbers and return the result."""
    return a + b
```

3. **여러 줄 독스트링**: 여러 줄에 걸친 설명이 필요한 경우, 첫 번째 줄은 짧은 요약, 그 뒤에 한 줄을 비워두고 그 뒤에 더 자세한 설명을 작성

```javascript
def comlex_function(a, b):
    """
    Perform a complex operation.
    
    This function does many things, and we need multiple lines to describe it.
    """
    pass
```

4. **인자와 반환 값에 대한 설명**: 인자와 반환값에 대한 정보를 포함하는 경우, 일반적으로는 `Args:` 라벨, 반환 값은 `Returns:` 라벨을 사용하여 기술

```javascript
def add(a, b):
    """
        Add two numbers and return the result.
        
        Args:
            a (int or float): The first number.
            b (int or float):  The second number.
        
        Returns:
            int or float: The sum of the two numbers.
    """
    return a + b
```

```javascript
> def fetch_smalltable_rows(
    table_handle: smalltable.Table,
    keys: Sequence[bytes | str],
    require_all_keys: bool = False,
) -> Mapping[bytes, tuple[str, ...]]:
    """Fetches rows from a Smalltable.

    Retrieves rows pertaining to the given keys from the Table instance
    represented by table_handle.  String keys will be UTF-8 encoded.

    Args:
        table_handle: An open smalltable.Table instance.
        keys: A sequence of strings representing the key of each table
          row to fetch.  String keys will be UTF-8 encoded.
        require_all_keys: If True only rows with values set for all keys will be
          returned.

    Returns:
        A dict mapping keys to the corresponding table row data
        fetched. Each row is represented as a tuple of strings. For
        example:

        {b'Serak': ('Rigel VII', 'Preparer'),
         b'Zim': ('Irk', 'Invader'),
         b'Lrrr': ('Omicron Persei 8', 'Emperor')}

        Returned keys are always bytes.  If a key from the keys argument is
        missing from the dictionary, then that row was not found in the
        table (and require_all_keys must have been False).

    Raises:
        IOError: An error occurred accessing the smalltable.
    """
```

For the site tree, see the [root Markdown](https://slashpage.com/yerim-devnote.md).
