new

메모리 할당

new 키워드를 사용하면 CLR은 관리되는 힙에 객체를 위한 메모리를 할당한다. 

할당된 메모리는 해당 객체에 대한 모든 참조가 없어질 때까지 메모리에 존재하고 더 이상 참조되지 않을 때 GC에 의해 관리된다.

public class MyClass
{
    public int Number { get; set; }
}

public class Program
{
    public static void Main()
    {
        MyClass myObject = new MyClass();
        myObject.Number = 1;
        Console.WriteLine(myObject.Number);
    }
}

 

 

생성자

생성자는 객체가 할당될 때 호출되는 생명주기 메서드(Lifecycle Methods)이다.

클래스의 객체를 생성하는 방식을 생각해 보면 new 키워드 뒤에 클래스명의 함수를 쓰는데 이 함수는 클래스에서 따로 작성하지 않았는데도 문제없이 컴파일된다.

 

MyClass myObject = new MyClass();

 

그 이유는 클래스에 별도로 생성자에 대한 작성을 하지 않아도 컴파일 단계에서 자동으로 기본 생성자를 만들어서 사용하기 때문에 컴파일 에러가 발생하지 않게 된다.

 

기본 생성자의 형태는 클래스 명의 메서드로 함수 내부에는 비어있는 형태로 볼 수 있다.

 

public class MyClass
{
    public int Number { get; set; }
    // 기본 생성자 형태
    public Number(){}
}

public class Program
{
    public static void Main()
    {
        MyClass myObject = new MyClass();
        myObject.Number = 1;
        Console.WriteLine(myObject.Number);
    }
}


생성자의 접근제한자를 private 등을 사용해서 클래스의 인스턴스 생성을 제한할 수 있다.

 

생성자는 파라미터를 추가한 형태로 선언이 가능하며 클래스의 인스턴스가 생성될 때 필드나 프로퍼티를 초기화하는 방법으로 사용할 수 있다.

 

public class MyClass
{
    public int Number { get; set; }
    private string _id;
    private string _pw;
    private int _age;
    private bool _isAgree;
    
    // 기본 생성자 형태
    public Number(string id, string pw, int age, bool isAgree)
    {
    	_id = id;
        _pw = pw;
        _age = age;
        _isAgree = isAgree;
    }
}

public class Program
{
    public static void Main()
    {
        MyClass myObject = new MyClass("bak", "****", 19, true);
        // 에러 발생
        MyClass myObject = new MyClass();
    }
}

 

이렇게 하면 인스턴스를 생성과 동시에 필드값을 초기화할 수 있다.

주의할 점은 이렇게 파라미터를 받는 생성자를 작성하게 되면 컴파일러에서는 더 이상 기본 생성자는 만들어 주지 않기 때문에 기본 생성자를 사용하려고 하면 컴파일 에러가 발생하게 되므로 기본 생성자도 사용하기를 원하면 추가로 작성해야 한다. 즉 생성자도 오버로딩이 가능하기 때문에 다양한 매개변수를 받는 생성자의 선언이 가능하다.

 

소멸자

생성자와는 호출 시점에만 차이가 있는 생명주기 메서드이다. (파괴자라고도 한다.)

소멸자는 객체가 소멸되는 시점에 호출되며 C#에서는 더 이상 객체가 참조되는 곳이 없을 때 GC에 의해서 관리되어 소멸될 때 소멸자가 호출된다.

 

따라서 소멸자의 호출 시점이 명확하지 않으므로 소멸자 내부에서 어떠한 기능을 수행시키게 한다면 동작에 대한 기대가 힘들기 때문에 C#에서는 이를 활용하는 경우는 드물다. 

 

public class MyClass
{
    public Number(){}
    // 소멸자 선언
    ~Number(){}
}

 

소멸자는 직접 호출도 불가능하기 때문에 별도의 접근 제한자를 지정할 필요도 없다.

728x90
반응형

딕셔너리는 해시 테이블 또는 키, 밸류라고 부른다. 

데이터는 중괄호 안에 선언되며 키와 밸류는 콜론으로 구분된다.

 

>>> dic_1 = {"key_1": 'value_1', 'key_2':"value_2"}
>>> dic_1["key_1"]
'value_1'
>>> dic_1['key_1']
'value_1'
>>> dic_1["key_2"]
'value_2'

키는 큰 따옴표 또는 작은따옴표를 사용해 선언할 수 있다.

키값의 경우 보통 문자열, 숫자, 튜플 등이 사용되고 밸류에는 어떠한 데이터 타입도 사용할 수 있다. 

 

딕셔너리의 특징은 맵 형식이기 때문에 순서가 보장되지 않는다. 따라서 인덱스를 통한 요소의 접근이나 첫 번째, 마지막 등의 순서가 필요한 정보에 대해서는 접근이 불가능하며 키값을 사용해서 접근해 사용한다.

 

>>> dic_1[0]
Traceback (most recent call last):
  File "<pyshell#9>", line 1, in <module>
    dic_1[0]
KeyError: 0

 

중복된 이름의 키를 사용하게 될 경우 에러는 발생하지 않지만 앞에 선언된 키, 밸류가 뒤에 값으로 덮어씌워진다.

 

>>> dic_2 = {'key_1':'val_1','key_1':'val_2'}
>>> dic_2['key_1']
'val_2'
>>> len(dic_2)
1

딕셔너리의 요소 개수를 반환하는 함수인 len()을 사용하면 앞에 선언된 요소가 존재하지 않는걸 알 수 있다.

 

 

728x90
반응형

튜플은 리스트처럼 배열로 요소를 저장할 수 있다.

요소를 선언할 때는 값을 콤마로 구분해서 저장이 가능하며 이때 소괄호를 사용해서 값을 감싸서 튜플로 표시하는 게 일반적이다.

>>> tuple_1 = 1, 2, 3
>>> tuple_2 = 4,
>>> tuple_3 = (5, 6, 7)
>>> tuple_1
(1, 2, 3)
>>> tuple_2
(4,)
>>> tuple_3
(5, 6, 7)

 

이렇게 튜플에 값을 할당하는것을 패킹이라고 한다.

 

이 튜플은 한 번에 여러 개의 변수에 값을 할당하는 게 가능한데 이것을 언패킹이라고 한다.

 

>>> tuple_1 = 4, 5, 6
>>> x, y, z = tuple_1
>>> x, y, z
(4, 5, 6)

 

불변성

튜플이 리스트와 다른 점은 선언된 이후에 값의 수정이 불가능하다.

>>> tuple_1 = 1, 2, 3
>>> tuple_1[0] = 4
Traceback (most recent call last):
  File "<pyshell#38>", line 1, in <module>
    tuple_1[0] = 4
TypeError: 'tuple' object does not support item assignment
>>> tuple_1 = 4, 5, 6
>>> tuple_1[0]
4
>>>

튜플의 요소에 인덱스로 접근하여 값을 변경하면 에러가 발생하지만 새로 값을 할당하는 것은 문제가 되지 않는다.

 

 

이러한 튜플의 특징을 활용해서 런타임에 값이 변하면 안 되는 정보를 저장하거나 또는 하나 이상의 정보가 조합을 이룰 때 의미를 가지는 데이터를 저장할 때 사용된다.

 

>>> tuple_1 = 4, 5, 6
>>> x, y, z = tuple_1
>>> x, y, z
(4, 5, 6)
>>> vector3 = (10, 2, -4)
>>> x, y, z = vector3
>>> x
10
>>> y
2
>>> z
-4
>>> x, y, z
(10, 2, -4)

 

 

여래 값을 전달할 수 있기 때문에 함수에서 여러 개의 값을 반환하거나 또는 매개변수로 전달이 필요할 때 등 다양하게 활용이 가능하다.

 

728x90
반응형

프로그래머들은 각자의 개발 철학을 가지고 있다.

프로그래밍 언어들의 다양한 특징들은 개발자들의 철학을 배경으로 만들어지게 된다.

 

파이썬 또한 개발자의 철학이 담겨 있는 프로그래밍 언어이다. 그 철학은 pep-20으로 알려진 문서에 담겨있다.

 

PEP 20 – The Zen of Python

문서의 제목을 번역하면 파이썬의 선이다.

여기서 선은 불교용어 선(禪)이다. 서구권에 선이라는 개념을 정착시킨게 일본 불교학자이다 보니 일본식 발음인 젠(zen)이 고유명사가 되었는데 문서에서 사용된 뜻이 불교의 선과 동일한 의미를 가지기 보다는 파이썬의 개발 철학이나 가치와 원칙 등 방향성을 나타내는 의미로 쓰인거같다. 제목도 일반적인 문서스럽지 않은데 이는 파이썬의 공식 문서 대부분이 비슷한 느낌을 준다.

 

문서의 저자를 보고 Tim Peters가 파이썬을 만든사람인줄 알았지만 알고보니 파이썬의 초기 개발자는 Guido van Rossum(귀도 반 로섬)이라는 네덜란드 개발자였다.

 

Foreword for "Programming Python"

 

파이썬의 서문에서는 탄생 배경에 대한 인터뷰 내용이 있다. 심심했던 그는 ABC 언어에 영감을 받고 취미로 만들기 시작했다고 하는데 그렇게 만들어진 언어가 지금까지도 많은 사람들에게 사용된다는게 그의 천재적인 면모가 보인다.

 

다시 파이썬의 선으로 돌아가서 저자인 Tim Peters는 파이썬 초기 설계부터 현재까지 개발과 커뮤니티에 많은 영향을 준 인물이다. 해당 문서는 커뮤니티에 파이썬의 가치와 철학을 공유하고 강조하기 위해서 작성되었으며 커뮤니티 안에서 협업할 때 지켜야할 원칙을 정리하고 제시하는 목적을 가지고 있다.

작성 배경이 그렇다보니 문서의 내용이 다소 가볍고 사용되는 표현들도 유머러스함이 보인다. 

 

Beautiful is better than ugly. (아름다운 것이 추한 것보다 낫다.)
Explicit is better than implicit. (명시적인 것이 암시적인 것보다 낫다.)
Simple is better than complex. (간결한 것이 복합적인 것보다 낫다.)
Complex is better than complicated. (복합적인 것이 복잡한 것보다 낫다.)
Flat is better than nested. (수평적인 것이 내포된 것보다 낫다.)
Sparse is better than dense. (여유로운 것이 밀집된 것보다 낫다.)
Readability counts. (가독성은 중요하다.)
Special cases aren't special enough to break the rules.
(특별한 경우들은 규칙을 어길 정도로 특별하지 않다.)
Although practicality beats purity. (실용성은 순수성을 이긴다.)
Errors should never pass silently. (에러는 절대로 조용히 지나가지 않는다.)
Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess.
(명시적으로 오류를 감추려는 의도가 아니라면 모호함을 대할 때, 이를 추측하려는 유혹을 거부하라.)
There should be one-- and preferably only one --obvious way to do it.
(명확하고 가급적이면 유일한 하나의 방법은 항상 존재한다.)
Although that way may not be obvious at first unless you're Dutch.
(네덜란드인이 아니면 비록 그 방법이 처음에는 명확해 보이지 않더라도. (네덜란드인은 
귀도 반 로섬을 의미하는것 같다.))
Now is better than never. (지금 행동에 옮기는 것이 아예 안 하는 것보다는 낫다.)
Although never is often better than *right* now.
(비록 아예 안 하는 것이 지금 *당장* 하는 것보다 나을 때도 많지만.)
If the implementation is hard to explain, it's a bad idea. (구현 결과를 설명하기 쉽지 않다면, 그것은 나쁜 아이디어이다.)
If the implementation is easy to explain, it may be a good idea.
(구현 결과를 설명하기 쉽다면, 그것은 좋은 아이디어일지도 모른다.)
Namespaces are one honking great idea -- let's do more of those!
(네임스페이스는 정말 훌륭한 아이디어다 -- 더 많이 사용하자!)

 

문서에서 반복해서 명확성, 간결성, 가독성을 강조한다. 이러한 철학으로 인해서 문법면에서는 엄격하며 이를 위한 스타일 가이드도 있다. (PEP 8)  이러한 코드 스타일들은 대부분 기술적인 제한 보다는 프로그래머들간에 지켜야할 관례이다.

 

예를 들어서 상수의 경우 모두 대문자로 표기하는 것을 규칙으로 한다.

하지만 일반 변수를 모두 대문자로 표기하고 그 값을 마음대로 바꾸어 사용한다고해서 실행이 안되거나 하지 않지만 다른 프로그래머들에게는 상수의 값이 변경되는 예상하지 못한 동작이 될 수 있고 이는 파이썬의 철학과 반대되는 행동이라 볼 수 있다.

 

 

728x90
반응형

리스트

순서를 가지는 객체의 모음이다.

list_1 = []	# 빈 리스트 	
list_2 = [0, 1] # 정수타입
list_3 = ['a', 'b', 'c'] # 문자타입
list_4 = [0, 1, 'a', 'b'] # 정수와 문자타입
list_5 = [0, ['a', 'b']] # 리스트는 리스트를 요소로 가질 수 있다.

 

0개 이상의 요소를 콤마로 구분하며 전체 요소는 대괄호로 감싼다.

 

값을 참조할 때는 대부분의 프로그래밍 언어에서 사용되는 배열과 마찬가지로 인덱스로 접근할 수 있다.

 

역시 첫 번째 인덱스는 0으로 시작한다.

 

>>> list_1 = []
>>> list[0]
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    list[0]
TypeError: 'type' object is not subscriptable
# 비어있기 때문에 값을 참조할 수 없다.

>>> list_2[1]
1

>>> list_3 = ['a','b']
>>> list_3[0]
'a'

>>> list_5[1][1]
'b'

 

리스트 내부에 리스트 요소는 다차원 배열의 접근과 유사하다.

 

함수

리스트는 다양한 함수를 사용해서 다룰 수 있다.

 

 

append

리스트 맨 끝에 요소를 추가한다.

>>> list_functions = []
>>> list_functions.append('a')
>>> list_functions.append('b')
>>> list_functions
['a', 'b']

 

insert

지정한 위치에 요소를 추가할 수 있다.

>>> list_functions.insert(0, 'aa')
>>> list_functions
['aa', 'a', 'b']
# 지정한 인덱스에 요소가 추가되고 그 뒤로 기존 요소들이 한칸씩 밀린.

 

pop

리스트의 마지막 요소를 반환 후 삭제한다.

>>> list_functions.pop()
'b'
>>> list_functions
['aa', 'a']

# 요소를 반환 후 해당 리스트에는 제거됨

 

remove

지정한 값과 동일한 요소를 삭제한다.

>>> list_functions = ['a', 'a', 'b']
>>> list_functions.remove('a')
>>> list_functions
['a', 'b']
# 동일한 요소가 있을 경우 먼저 나오는 요소가 제거된다.

 

index

요소의 인덱스를 반환한다.

>>> list_functions.index('a')
0
>>> list_functions.append('a')
>>> list_functions.index('a')
0
# 동일한 요소가 있을 경우 먼저 나오는 요소의 인덱스를 반환

 

count

리스트 내에서 지정한 값과 동일한 요소의 개수를 반환한다.

>>> list_functions.count('a')
2

 

sort

요소들을 정렬한다. 

>>> list_char = ['d', 'a', 'e', 'c', 'b']
>>> list_int = [3, 2, 5, 4, 1]
>>> list_char.sort()
>>> list_int.sort()
>>> list_char
['a', 'b', 'c', 'd', 'e']
>>> list_int
[1, 2, 3, 4, 5]

오름차순으로 정렬되는 것으로 보이지만 정확하게는 기본값이 오름차순이고 이는 함수의 매개변수를 통해 설정가능하다.

>>> list_char_inc = ['d', 'a', 'e', 'c', 'b']
>>> list_char_dec = ['d', 'a', 'e', 'c', 'b']
>>> list_char_inc.sort(reverse=False) # defualt가 False이기 때문에 매개변수가 없으면 오름차순
>>> list_char_dec.sort(reverse=True)
>>> list_char_inc
['a', 'b', 'c', 'd', 'e']
>>> list_char_dec
['e', 'd', 'c', 'b', 'a']

 

reverse

요소들을 역순으로 정렬한다.

>>> list_char = ['d', 'a', 'e', 'c', 'b']
>>> list_char.reverse()
>>> list_char
['b', 'c', 'e', 'a', 'd']

 

clear

리스트의 요소를 모두 제거한다.

>>> list_clear = [1, 2, 3, 4, 5, 6]
>>> list_clear
[1, 2, 3, 4, 5, 6]
>>> list_clear.clear()
>>> list_clear
[]

 

728x90
반응형

데이터 타입

파이썬에서 다룰 수 있는 가장 기본적인 데이터의 종류는 정수, 부동소수점, 문자열, 부울값이 있다.

정수 int 소수점이 없는 수치
부동소수점 float 소수가 있는 수치
문자열 string 문자의 나열
부울값 bool True, False

 

이러한 타입들은 엄밀하게 구분되는데 type() 함수를 사용하여 변수나 값의 타입에 대한 정보를 알 수 있다.

연산 과정이 있어도 결과 값으로 타입이 결정된다.

문자열을 값을 할당할 때는 큰 따옴표("") 또는 작은따옴표('')로 문자를 감싼다.

일반적인 문자열을 감쌀 때는 두 부호가 동일하게 동작을 하지만 특수한 상황에서 다르게 사용한다.

 

만약 문자열 안에 부호가 포함되어 있는 상황에서는 문자열의 범위를 표현하려던 부호가 의도와 다르게 적용될 수 있다.

Hello "Python"!
I'm Bak

a = "Hello "Python"!"

b = 'I'm Bak'

이런 경우에는 문자열을 해석할 때 오류가 발생하지 않도록 두 종류의 방식을 모두 사용할 수 있도록 한다.

 

형변환

type casting

데이터형을 다른 데이터 형으로 변환하는 것을 뜻한다.

Int

int() : 데이터 타입을 정수로 변환시킨다.

 

Float

float() : 데이터 타입을 부동소수점으로 변환한다.

 

String

str() : 데이터 타입을 문자열로 변환한다.

 

Bool

bool은 어떤 조건이 성립했는지 아닌지 처리를 바꾸면서 실행된다. 

True와 False 둘 중 하나로 존재한다.

 

bool()을 사용하면 입력된 식이나 값을 평가해서 bool 타입의 값으로 출력한다. 이때 0의 경우 false 그 외의 값들은 모두 true로 평가된다.

 

728x90
반응형

함수는 여러 개의 처리를 기능별로 모아 놓은 것이다. 

사용할 때는 함수가 어떤 기능을 하는지만 알아도 되며 내부에서 처리되는 과정들은 알 필요가 없다.

 

이때 함수에 전달하는 데이터를 인수, 함수로부터 돌아오는 값을 반환값이라고 한다.

 

필요에 따라 직접 함수를 구현해서 사용할 수 있지만 파이썬에는 미리 준비된 함수도 많이 제공된다.

 

예를 들어서 두 개의 값을 비교해서 더 크거나 또는 작은 값을 구하는 처리가 필요한 경우가 빈번하게 사용되는 상황일 때, 매번 값을 비교하는 과정을 작성하는 것은 비효율적이다. 이럴 때 함수를 만들어서 처리하면 코드가 간결해진다. 

만약 필요한 함수가 파이썬에서 제공되는 것이라면 직접 구현하는 과정도 생략이 될 수 있다.

 

예시에서 처리하는 기능의 경우 파이썬에서 max(), min() 함수가 있다.

max(a, b)  : a와 b 중 큰 값을 반환

min(a, b) : a와 b 중 작은 값을 반환 

 

함수는 기본적으로 함수명() 형태로 선언되며 실행할 때 괄호를 붙여 실행한다. 어떠한 값을 입력해야 한다면 괄호 안에 변수나 값을 넣는다.

 

 

728x90
반응형

변수명

파이썬에서 변수명으로 사용이 가능한 문자는 다음과 같다.

대소 영문자, 숫자, 언더스코어이다. 여기서 숫자는 맨 앞에 올 수 없다.

 

이외에 예약어로 지정되어 있는 키워드들도 변수명으로 사용이 불가능하다.

 

대입 간이 기법

변수의 값이 자주 갱신되는 프로그래밍에서 값을 증가시키고 감소시키는 처리에서는 간이 기법을 사용한다.

수학에서는 적용되지 않는 a = a + 1과 같은 서식을 사용할 수 있다. 

동작은 우변을 먼저 계산하고 결과를 좌변의 변수에 대입한다.

 

연산을 하고 다시 자신에게 대입하는 처리보다 더 간단한 기술방법이 있다.

 

 

+= 자기 자신에게 우변값을 더하고, 그 결과를 자기 자신에 대입한다.
-= 자기 자신에서 우변값을 빼고, 그 결과를 자기 자신에게 대입한다.
*= 자기 자신에게 우변값을 곱하고, 그 결과를 자기 자신에게 대입한다.
/= 자기 자신을 우변값으로 나누고, 그 결과를 자기 자신에게 대입한다.

 

728x90
반응형

사칙연산

수학에서 사용되는 사칙연산을 그대로 사용할 수 있다. 

  수학 기호 파이썬 기호
덧셈 + +
뺄셈 - -
곱셈 x *
나눗셈 ÷ /

 

수학에서 사용하는 연산 규칙이 그대로 적용된다.

 

기타 연산

사칙연산 이외에도 일반적인 컴퓨터 사용하는 계산 기호들을 사용할 수 있다.

 

나머지를 구한다. %
몫을 정수로 구한다. //
지수를 구한다. **

 

728x90
반응형

IDLE

Intergrated Development Environment, 통합 개발 환경

파이썬 1.5.2B1 이후에 같이 설치되는 통합 개발 환경이다. 파이썬 명령어를 쉽게 사용할 수 있도록 제공되는 GUI 툴이다.

 

기본적인 연산 동작을 IDLE로 테스트해 본다.

IDLE은 시작에서 IDLE을 검색해서 찾아서 명령어창을 실행시킬 수 있다.

 

IDLE에는 여러 기능들이 제공된다.

 

자동완성

명령어를 빠르게 입력하거나 제공되는 함수를 찾을 수 있다.

 

구문강조

 

등의 편의성을 제공한다.

728x90
반응형

+ Recent posts