본문 바로가기

Python

220127 학습일기

오늘도 점프 투 파이썬

1.

class Fourcal:
    def set_data(self,first,second):
        self.first = first
        self.second = second

setdata 메소드는 매개변수로 self, first, second 3개의 입력값을 받는다.
그런데 여기서 일반함수와는 다르게 메서드의 첫번째 매개변수 self는 특별한 의미를 가진다.

 

class FourCal:
    def setdata(self, first, second):
        self.first = first
        self.second = second
        
a = FourCal()
a.setdata(4,2)

a 객체를 만들고 a 객체를 통해 setdata 메소드를 호출했다.

근데 뭔가 좀 이상하다.
setdata 메소드에는 self, first, second 총 3개의 매개변수가 필요한데 실제로는 2개(4,2)만 전달했다.

a.setdata(4,2) 처럼 호출하면 setdata 메서드의 첫번째 매개변수 self에는 setdata 메소드를 호출한 객체 a가 자동으로 전달된다.

파이썬 메소드의 첫번째 매개변수 이름은 관례적으로 self를 사용한다,
객체를 호출할 때 호출한 객체 자신이 전달되기 때문에 self를 사용한 것이다.
self말고 다른 이름을 사용해도 상관없다.

 

메소드의 첫번째 매개변수 self를 명시적으로 구현하는 것은 파이썬만의 독특한 특징이다.
자바같은 언어는 첫번째 매개변수 self가 필요없다.

 

 

2.

메소드의 호출방법은 두가지이다.

 

1에 해당하는 방법이다.

객체.메소드(....)

예시는 아래와 같이.

class FourCal:
    def setdata(self, first, second):
        self.first = first
        self.second = second
        
a = FourCal()
a.setdata(4,2)

a.setdata(4,2)에서 반드시 self 매개변수에 해당하는 인자는 생략해주어야 한다.

 

클래스이름.메소드(객체이름,...)

이 형태로 호출할 때는 객체를 첫번째 매개변수 self에 꼭 전달해 주어야 한다.

 

예시는 아래와 같다.

class FourCal:
    def setdata(self, first, second):
        self.first = first
        self.second = second
        
a = FourCal()
FourCal.setdata(a,4,2)

 

 

3.

객체에 생성되는 객체만의 변수를 객체변수라고 부른다.

 

class FourCal:
    def setdata(self, first, second):
        self.first = first
        self.second = second
        
a = FourCal()
a.setdata(4,2)

이때 setdata 메소드의 수행문은 다음과 같이 해석된다.

self.first = 4
self.second = 2

 

self는 전달된 객체 a이므로 다시 다음과 같이 해석된다.

a.first = 4
a.second = 2

a.first = 4 문장이 수행되면 a객체에 객체변수 first가 생성되고 값 4가 저장된다.

 

 

아래를 통해 확인할 수 있다.

class FourCal:
    def setdata(self, first, second):
        self.first = first
        self.second = second
        
a = FourCal()
a.setdata(4,2)
print(a.first)
print(a.second)

<출력값>

4
2

 

 

4.

클래스로 만든 객체의 객체변수는 다른 객체의 객체변수와 상관없이 독립적인 값을 유지한다.

 

아래를 통해 확인할 수 있다.

class introduce:
    def say(self,first,second):
        self.first = first
        self.second = second

a= introduce()
b= introduce()

a.say("a의 첫번째 객체변수","a의 두번째 객체변수")
b.say("b의 첫번째 객체변수","b의 두번째 객체변수")

print(a.first)
print(b.first)

<출력값>

a의 첫번째 객체변수
b의 첫번째 객체변수

 

id값으로 확인할 수도 있다.

class introduce:
    def say(self,first,second):
        self.first = first
        self.second = second

a= introduce()
b= introduce()

a.say("a의 첫번째 객체변수","a의 두번째 객체변수")
b.say("b의 첫번째 객체변수","b의 두번째 객체변수")

print(id(a))
print(id(b))

<출력값>

2329397301200
2329397301152

 

a객체의 first 주소값과 b 객체의 first 주소 값이 서로 다르므로 각각 다른 곳에 그 값이 저장된다는 것을 알 수 있다.

 

객체변수는 그 객체의 고유 값을 저장할 수 있는 공간이다. 

객체 변수는 다른 객체들 영향받지 않고 독립적으로 그 값을 유지한다.

 

 

5.

사칙연산 계산기를 만들어 보았다.

class FourCal:
    def setdata(self,first,second):
        self.first = first
        self.second = second
    def add(self):
        result = self.first +self.second
        return result
    def sub(self):
        result = self.first -self.second
        return result
    def mul(self):
        result = self.first * self.second
        return result
    def div(self):
        result = self.first / self.second
        return result

a = FourCal()
a.setdata(4,2)
k = a.div()
print(k)

 

 

6.

객체에 초깃값을 설정해야 할 필요가 있을 때 setdata와 같은 메서드를 호출하여 초깃값을 설정하기보다는 생성자를 구현하는 것이 안전한 방법이다.
생성자(Constructor)란 객체가 생성될 때 자동으로 호출되는 메서드를 의미한다.

 

파이썬 메소드 이름으로 __init__을 사용하면 이 메소드는 생성자가 된다.

 

5번의 코드에서 setdata 메소드를 지우고 생성자를 입력해보자.

class FourCal:
    def __init__(self,first,second):
        self.first = first
        self.second = second
    def add(self):
        result = self.first +self.second
        return result
    def sub(self):
        result = self.first -self.second
        return result
    def mul(self):
        result = self.first * self.second
        return result
    def div(self):
        result = self.first / self.second
        return result

이제 a라는 객체를 생성하면 자동으로  __init__ 메소드가 호출된다.

 

이제 a라는 객체를 생성해보자.

class FourCal:
    def __init__(self,first,second):
        self.first = first
        self.second = second
    def add(self):
        result = self.first +self.second
        return result
    def sub(self):
        result = self.first -self.second
        return result
    def mul(self):
        result = self.first * self.second
        return result
    def div(self):
        result = self.first / self.second
        return result

a = FourCal()

이러면 아래와 같은 오류가 뜬다.

    a = FourCal()
TypeError: __init__() missing 2 required positional arguments: 'first' and 'second'

생성자의 매개변수인 first와 second에 해당하는 값이 전달되지 않았기 때문이다.

 

 

오류를 해결하려면 아래와 같이 a라는 객체를 생성하면서 생성자의 매개변수에 해당하는 값을 전달해줘야 한다.

class FourCal:
    def __init__(self,first,second):
        self.first = first
        self.second = second
    def add(self):
        result = self.first +self.second
        return result
    def sub(self):
        result = self.first -self.second
        return result
    def mul(self):
        result = self.first * self.second
        return result
    def div(self):
        result = self.first / self.second
        return result

a = FourCal(1,2)

그러면 __init__메소드의 매개변수에 대입되는 값은 다음과 같다.

  • self: a
  • first : 1
  • second: 2
class FourCal:
    def __init__(self,first,second):
        self.first = first
        self.second = second
    def add(self):
        result = self.first +self.second
        return result
    def sub(self):
        result = self.first -self.second
        return result
    def mul(self):
        result = self.first * self.second
        return result
    def div(self):
        result = self.first / self.second
        return result

a = FourCal(1,2)
print(a.first)
print(a.second)

<출력값>

1
2

 

 

다른 메소드들도 다 잘 작동한다.

class FourCal:
    def __init__(self,first,second):
        self.first = first
        self.second = second
    def add(self):
        result = self.first +self.second
        return result
    def sub(self):
        result = self.first -self.second
        return result
    def mul(self):
        result = self.first * self.second
        return result
    def div(self):
        result = self.first / self.second
        return result

a = FourCal(1,2)
print(a.add())
print(a.sub())
print(a.mul())
print(a.div())

<출력값>

3
-1
2
0.5

 

 

7.

어떤 클래스를 만들 때 다른 클래스의 기능을 물려받을 수 있다.
이것이 클래스의 상속이다.

 

클래스를 상속하기 위해서는 상속받는 클래스 이름 뒤 괄호 안에 상속하는 클래스 이름을 넣어주면 된다.

class 상속받는 클래스 이름(상속하는 클래스 이름)

 

 

class FourCal:
    def __init__(self,first,second):
        self.first = first
        self.second = second
    def add(self):
        result = self.first +self.second
        return result
    def sub(self):
        result = self.first -self.second
        return result
    def mul(self):
        result = self.first * self.second
        return result
    def div(self):
        result = self.first / self.second
        return result

class MoreFourCal(FourCal):
    pass

MoreFourCal은 FourCal 클래스를 상속받았으므로 FourCal 클래스의 모든 기능을 사용할 수 있어야 한다.

 

class FourCal:
    def __init__(self,first,second):
        self.first = first
        self.second = second
    def add(self):
        result = self.first +self.second
        return result
    def sub(self):
        result = self.first -self.second
        return result
    def mul(self):
        result = self.first * self.second
        return result
    def div(self):
        result = self.first / self.second
        return result

class MoreFourCal(FourCal):
    pass

b= MoreFourCal(2,3)
print(b.add())

<출력값>

5

 

 

8.

상속은 왜 할까?

 

보통 상속은 기존 클래스를 변경하지 않고 기능을 추가하거나 기존 기능을 변경하려고 할 때 사용한다.
특히 기존 클래스가 라이브러리 형태로 제공되거나 수정이 허용되지 않는 상황이라면 상속을 사용해야한다.

 

 

9.

MoreFourCal에 제곱을 할 수 있는 메소드를 추가해보자.

class FourCal:
    def __init__(self,first,second):
        self.first = first
        self.second = second
    def add(self):
        result = self.first +self.second
        return result
    def sub(self):
        result = self.first -self.second
        return result
    def mul(self):
        result = self.first * self.second
        return result
    def div(self):
        result = self.first / self.second
        return result

class MoreFourCal(FourCal):
    def pow(self):
        result = self.first ** self.second
        return result

b= MoreFourCal(2,3)
print(b.pow())

<출력값>

8

 

 

10.

class FourCal:
    def __init__(self,first,second):
        self.first = first
        self.second = second
    def add(self):
        result = self.first +self.second
        return result
    def sub(self):
        result = self.first -self.second
        return result
    def mul(self):
        result = self.first * self.second
        return result
    def div(self):
        result = self.first / self.second
        return result

a = FourCal(3,0)
print(a.div())

이 코드를 실행하면 아래와 같은 오류가 뜬다.

ZeroDivisionError: division by zero

3을 0으로 나누니 zerodivisionerror가 뜬 것이다.

 

근데 0으로 나눌 때 오류가 아닌 0을 돌려주도록 만들고 싶다면 어떻게 해야할까?

클래스 하나를 더 만들어보자.

class FourCal:
    def __init__(self,first,second):
        self.first = first
        self.second = second
    def add(self):
        result = self.first +self.second
        return result
    def sub(self):
        result = self.first -self.second
        return result
    def mul(self):
        result = self.first * self.second
        return result
    def div(self):
        result = self.first / self.second
        return result

class SafeFourCal(FourCal):
    def div(self):
        if self.second ==0:
            result =0
        else:
            result = self.first / self.second
        return result

a = SafeFourCal(3,0)
print(a.div())

<출력값>

0

SafeFourCal 클래스는 FourCal 클래스에 있는 div 메소드를 동일한 이름으로 다시 작성하였다.
이렇게 부모 클래스에 있는 메소드를 자식 클래스에 동일한 이름으로 다시 만드는 것을 메소드 오버라이딩(Overriding:덮어쓰기)라고 한다.
이렇게 메소드를 오버라이딩하면 부모클래스의 메소드 대신 오버라이딩한 메소드가 호출된다.

 

 

11.

클래스 변수는 클래스 안에 변수를 선언하여 생성한다.

class Hi:
    MyName = '승니'   #클래스 변수

print(Hi.MyName)

<출력값>

승니

 

 

 

클래스 변수는 

클래스 이름.클래스 변수

로도 사용할 수 있다

 

 

 

 

class Hi:
    MyName = '승니'   #클래스 변수

a = Hi()
b = Hi()

print(a.MyName)
print(b.MyName)

<출력값>

승니
승니

 

 

 

 

class Hi:
    MyName = '승니'   #클래스 변수

a = Hi()
b = Hi()

Hi.MyName = 'Tina'

print(a.MyName)
print(b.MyName)

<출력값>

Tina
Tina

클래스 변수 MyName의 값을 변경했더니 클래스로 만든 모든 객체의 MyName 값이 변경되었다.
즉 클래스 변수는 클래스로 만든 모든 객체에 공유된다는 특징이 있다.

 

이걸 id함수로 확인하는 방법이 있다.

class Hi:
    MyName = '승니' 

a = Hi()
b = Hi()

print(id(a.MyName))
print(id(b.MyName))

<출력값>

2805180656112
2805180656112

id값이 모두 같으므로 a.MyName, b.MyName 은 모두 같은 메모리를 가리키고 있다.

 

실제로 클래스에서는 클래스 변수보다 객체변수가 훨씬 중요하다.
실무 프로그래밍할 때에도 클래스 변수보다 객체변수를 사용하는 비율이 훨씬 높다고 한다.

 

 

 

 

 

[교재]

https://wikidocs.net/book/1

 

점프 투 파이썬

** 점프 투 파이썬 오프라인 책(개정판) 출간 !! (2019.06) ** * [책 구입 안내](https://wikidocs.net/4321) 이 책은 파이썬 ...

wikidocs.net

 

'Python' 카테고리의 다른 글

220206 학습일기  (0) 2022.02.07
220203 학습일기  (0) 2022.02.06
220123 학습일기  (0) 2022.01.23
220120 학습일기  (0) 2022.01.20
[sw expert acadmey] 1859. 백만 장자 프로젝트  (0) 2022.01.19