Skip to content

Commit

Permalink
Update 3. Functions.md
Browse files Browse the repository at this point in the history
  • Loading branch information
deepbig authored Apr 22, 2024
1 parent 0a7e550 commit 4046b5e
Showing 1 changed file with 178 additions and 3 deletions.
181 changes: 178 additions & 3 deletions hong/python/effective-python/3. Functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,119 @@ minimum, maximum, median, average, count = get_stats(lengths)

이보다 더 많은 값을 언패킹 해야 한다면 경량 클래스(lightweight class)나 namedtuple을 사용하고 함수도 이런 값을 반환하게 만드는 것이 낫다.

** TODO: 경량 클래스(lightweight class), namedtuple 조사하기
** 경량 클래스(lightweight class)

- 경량 클래스 종류:  [TracebackException](https://docs.python.org/ko/3/library/traceback.html#traceback.TracebackException)[StackSummary](https://docs.python.org/ko/3/library/traceback.html#traceback.StackSummary) 및 [FrameSummary](https://docs.python.org/ko/3/library/traceback.html#traceback.FrameSummary). (Contributed by Robert Collins in [bpo-17911](https://bugs.python.org/issue?@action=redirect&bpo=17911).)
- dataclass: ***Lightweight class*** with less boilerplate for data.
- class: Creates objects that encapsulate what it is (identity)

** namedtuple

- collections module에 속한 Factory Function.
- `namedtuple() Factory Function for Tuples with Named Fields
- factory function for creating tuple subclasses with named fields
- Named tuples assign meaning to each position in a tuple and allow for more readable, self-documenting code. They can be used wherever regular tuples are used, and they add the ability to access fields by name instead of position index.
- Collections에 속한 class objects
- namedtuple()
- deque
- ChainMap
- Counter
- OrderedDict
- defaultdict
- UserDict
- UserList
- UserString

```python
# Basic example
Point = namedtuple('Point', ['x', 'y'])
p = Point(11, y=22) # instantiate with positional or keyworad arguments
p[0] + p[1] # indexable like the plain tuple (11, 22)
# Output: 33
x, y = p # unpack like a regular tuple
x, y
# Output: (11, 22)
p.x + p.y # fields also accessible by name
# Output: 33
p # readable __repr__ with a name=value style
# Point(x=11, y=22)
```

- Named tuples are especially useful for assigning field names to result tuples returned by the `csv` or `sqlite3` modules:

```python
EmployeeRecord = namedtuple('EmployeeRecord', 'name, age, title, department, paygrade')

import csv
for emp in map(EmployeeRecord._make, csv.reader(open("employees.csv", "rb"))):
print(emp.name, emp.title)

import sqlite3
conn = sqlite3.connect('/companydata')
cursor = conn.cursor()
cursor.execute('SELECT name, age, title, department, paygrade FROM employees')
for emp in map(EmployeeRecord._make, cursor.fetchall()):
print(emp.name, emp.title)
```

In addition to the methods inherited from tuples, named tuples supports three additional methods and two attributes. To prevent conflicts with field names, the method and attribute names start with an underscore.

_make(iterable)

- Class method that makes a new instance from an existing sequence or iterable.

```python
t = [11, 22]
Point._make(t)
# Output: Point(x=11, y=22)
```

_asdict()

- Return a new dict which maps field names to their corresponding values:

```python
p = Point(x=11, y=22)
p._asdict()
# Output: OrderedDict([('x', 11), ('y', 22)])
```

_replace(**kwargs)

- Return a new instance of the named tuple replacing specified fields with new values:

```python
p = Point(x=11, y=22)
p._replace(x=33)
# Output: Point(x=33, y=22)
```

_fields

- Tuple of strings listing the field names. Useful for introspection and for creating new named tuple types from existing named tuples.

```python
p._fields # view the field names
# Output: ('x', 'y')
Color = namedtuple('Color', 'red green blue')
Pixel = namedtuple('Pixel', Point._fields + Color._fields)
Pixel(11, 22, 128, 255, 0)
# Output: Pixel(x=11, y=22, red=128, green=255, blue=0)
```

_field_defaults

- Dictionary mapping field names to default values.

```python
Account = namedtuple('Acount', ['type', 'balance'], defaults=[0])
Account._field_defaults
# Output: {'balance': 0}
Account('premium')
# Output: Account(type='premium', balance=0)
```

출처: [collections — Container datatypes — Python 3.7.17 문서](https://docs.python.org/ko/3.7/library/collections.html)

### 기억해야 할 내용

Expand Down Expand Up @@ -167,7 +279,19 @@ def careful_divide(a: float, b: float) -> float:

- 이제 입력 출력, 예외적인 동작이 모두 명확해졌고, 호출자가 이 함수를 잘못 처리할 가능성이 매우 낮아졌다.

**TODO: 추가 조사 필요 (파이썬의 점진적 타입 지정(gradual typing)에서는 함수의 인터페이스에 예외가 포함되는지 표현하는 방법(이런 방식을 검증 오류(checked exception)라고 한다)이 의도적으로 제외됐다)
** 점진적 타입 지정(gradual typing):

- Gradual typing allows parts of a program to be dynamically typed and other parts to be statically typed. That means, the programmer can choose which part of the program he/she want to type check.
- You can gradually introduce types into your code.

** 검증 오류(checked exception):

- A checked exception is a contract between a function that declares and throws an exception and another function that calls those function and has to handle the exception in its body.
- 함수의 인터페이스에 예외가 포함되는지 표현하는 방법은 Python에서 의도적으로 제외됐다.
- 제외 이유:
- Open/Closed 원칙의 위배
- Checked Exception을 처리하지 않고 상위 계증으로 던지려면 반드시 메소드 시그니처의 throws에 명시해야한다. 예외의 처리를 강제하는 장점이 되기도 하지만, 시그니처를 수정해야하는 경우, 던진 계층부터 처리한 계층까지 거치는 모든 메소드에서 Checked 예외를 수정해야 하기 때문에 open-closed 원칙에 위배된다.
- 없이도 견고한 프로그래밍이 가능.

### 기억해야 할 내용

Expand Down Expand Up @@ -629,11 +753,62 @@ fibonacci(n)

파이썬 언어에서 함수의 인터페이스를 처리하려면 이런 애트리뷰트도 보존돼야 한다. wraps를 사용하면 이 모든 애트리뷰트를 제대로 복사해서 함수가 제대로 제대로 작동하도록 해준다.

** TODO: Introspection, reflection 조사
** Code Introspection (내성, 자기성찰):

- Introspection is an ability to determine the type of an object at runtime.
- Everything in python is an object. Every object in Python may have attributes and methods.
- By using introspection, we can dynamically examine python objects.
- Code Introspection is used for examining the classes, methods, objects, modules, keywords and get information about them so that we can utilize it.
- Python provides some built-in functions that are used for code introspection. They are:
1. type(): This function returns the type of an object.

```python
import math

print(type(math)) # Output: <class 'module'>
print(type(1) # Output: <class 'int'>
print(type("1") # Output: <class 'str'>
```

1. dir(): This function return list of methods and attributes associated with that object.
2. str(): This function converts everything into a string.
3. id(): This function returns a special id of an object.

[Code introspection in Python - GeeksforGeeks](https://www.geeksforgeeks.org/code-introspection-in-python/)

** reflection (반사, 심사숙고):

- Reflection refers to the ability for code to be able to examine attributes about objects that might be passed as parameters to a function.
- For example, if we write type(obj) then Python will return an object which represents the type of obj.
- Using reflection, we can write one recursive reverse function that will work for strings, lists, and any other sequence that supports slicing and concatenation.

```python
# Python program to illustrate reflection
def reverse(sequence):
sequence_type = type(sequence) # 여기서 타입에 맞는 동작을 수행함.
empty_sequence = sequence_type()

if sequence == empty_sequence:
return empty_sequence

rest = reverse(sequence[1:])
first_sequence = sequence[0:1]

final_result = rest + first_sequence

return final_result

print(reverse([10, 20, 30, 40]) # Output: [40, 30, 20, 10]
print(reverse("GeeksForGeeks")) # Output: skeeGroFskeeG
```

- introspection: 실행 시점에 프로그램이 어떻게 실행되는지 관찰하는 것을 뜻한다.
- reflection: 실행 시점에 프로그램을 조작하는 것을 뜻한다.

introspection은 실행 시에 object에 대한 정보를 알아내는 것, Reflection은 여기에서 그치지 않고 object에 대한 정보를 수정하는 것을 의미합니다. 엄밀히 따지면, 두가지의 의미가 다르지만 Reflection으로 합쳐서 부르는 경우가 많다.

[reflection in Python - GeeksforGeeks](https://www.geeksforgeeks.org/reflection-in-python/)

### 기억해야 할 내용

- 파이썬 데코레이터는 실행 시점에 함수가 다른 함수를 변경할 수 있게 해주는 구문이다.
Expand Down

0 comments on commit 4046b5e

Please sign in to comment.