본문 바로가기

Phython

파이썬의 naming, expression

a = 2

파이썬에서 a = 2 를 정의할 때,

a를 변수라고 하면 50점짜리 점수! (이건 프로그래밍 관점)

a는 name 또는 identify 라고 부르는게 정답!

그럼 = 기준 오른쪽은 expression(하나의 결과값으로 축약할 수 있는 것)이라고 부른다.

= 은 binding 이라고 부른다. 

 

a=2라고 지정하면, 이때 2는 int 타입으로 저장된다. 즉,  사용자가 굳이 명확하게 지정하지 않아도

type을 결정한다. 내부적으로 메모리 공간을 할당. 

 

naming

literal 

:expression에 붙이는 특수 기호 

 integer 

. 이 있으면 float

j가 있으면 complex (허수)

 

파이썬의 naming (PEP8 참고)

- 예약어로는 이름을 못 만든다. 밑의 식으로 확인 가능

import keyword
keyword.kwlist

- 숫자나 특수문자로 시작할 수 없다. 

- 단, _로 시작하는 경우는 예외  (_를 붙이면 특수한 용법으로 사용할 수 있다.)

-상수 취급할 때 대문자로 써라. (파이썬에는 상수라는 개념이 없다)

  * 상수 : 한 번 메모리에 할당하면 그 값을 바꿀 수 없는 것. 

  * 변수 : ... 바꿀 수 있는 것. 

- 함수 : snake 방식 (땅바닥을 기어다니는 뱀의 모양과 비슷하다고 해서 붙은 이름.

모두 소문자(혹은 모두 대문자)로 쓰되, 띄어쓰기를 밑줄(_) 기호로 대체하는 것이다.)

  ex) moon_beauty 

- 클래스 : camel (python) (첫 글자를 대문자로 적되, 맨 앞에 오는 글자는 소문자로 표기)

ex) moonBeauty 

      MoonBeauty (pascal  = caps word)

- 내가 정의한 클래스는 camel 스타일, 파이썬에서 제공하는 클래스들은 소문자로만!

 


 

expression

- lambda : 익명함수 또는 함수 식. lambda함수도 하나의 expression 취급. 

- 파이썬은 4가지 숫자형을 갖는다.  1. integer, 2.float, 3complex, 4. 

- 정수형도 4가지 (bit 관점) 1. binary(2진밥), 2.bin(10진법), 3.oct(8진법), 4.hex(16진법)

- float : 부동소수. 무한대(inf), 허수, 숫자가 아닌 애도 float으로 관리한다. 

0.2+0.1
0.9+0.1

위 결과는 0.3으로 딱 떨어지는 결과가 나오지 않지만, 밑의 결과는 1로 딱 떨어진다. 

>>> 0.2+0.1 == 0.3
False

>>> 0.9+0.1==1
True

1e2==100
type(1e2)
type(100)
1e2 is 100

실행시, 주의해야 할 점. 

>>> 1e2==100
True
>>> type(1e2)
<class 'float'>
>>> type(100)
<class 'int'>
>>> 1e2 is 100
<stdin>:1: SyntaxWarning: "is" with a literal. Did you mean "=="?
False

 

is : 메모리 번지 값까지 같은지 check함.

 

반면, ==는 주의해서 사용해야 한다. 

float 는 빨리 연산하기 위해서 근사적으로 연산한다. 


Atomic vs Container

Atomic 원자성
100_000_00 #숫자는 어떤 수자가 와도 쪼갤 수 없다.

>>> 100_000_00
10000000

 

atomic <-> container
구분 기준 : 
  -- homo(같은 데이터타입을 갖고 있음) / hetero
     -> 문자열, range, numpy, tensor, array / 다양한 데이터 타입을 갖을 수 있음.
  -- sesquence / non-sequence
   -- (iterable / non-iterable)
  -- mutable / immutable

 

문자열 (3가지) - 문자열은 순서가 중요하다. 

- str(string)

- bytes (immutable) 

- bytearray (mutable)

(memoryview)

 

* list : mutable

* tuple : immutable

 

*set : mutable
*frozenset : immutable

 

*mutable (변하기 쉬운): 잘 사용하면 편리하지만, 잘 못 사용하면 문제점이 많음. 

그래서 mutable이 없는 프로그래밍 언어가 많음. 

 

sequence data type은 순서가 중요하다.

dir() 시행 시, 리스트에 __getitem__, __len__이 있는 경우가 해당됨. 


numpy 는 c로 만들어짐. 

import sys
sys.maxsize

를 통해 maxsize 확인 가능. 

>>> sys.maxsize
9223372036854775807

 

sys.float_info
a == a+1
b = 1.7976931348623157e+308
b+1
b == b+1
1.7976931348623157e+309

>>> a == a+1
False                                      # a 변수를 정의하기 전에 a = a+1이라고 하면 거짓. 
>>> b = 1.7976931348623157e+308
>>> b+1    
1.7976931348623157e+308  # b를 최대값으로 설정해 두었을 때, 1 정도를 더해도 그 값이 변하지 않는 것을 확인
>>> b == b+1
True                                         # 그래서, b==b+1도 true로 나옴. 

>>> 1.7976931348623157e+309
inf                                             #최대값의 데이터 형태는 정수.

 


Boolean 자료 형태

type(True)
issubclass(bool, int)
True.__class__.__bases__
# bool 타입의 부모 형태는 int이다.

기본적으로 불리언의 자료 형태는 정수 -> 거짓은 0, 참은 1

>>> type(True)
<class 'bool'>
>>> issubclass(bool, int)
True

>>> True.__class__.__bases__
(<class 'int'>,)</class 'int'>

 

str(True)

True + True

>>> str(True)
'True'
>>> True + True
2

따라서 이런 결과가 도출됨. 


 

문자열 

a = '문근영'    #encoding
a = u'문근영'   #unicode
b = b'문근영'   #bytes 는 지원하지 않음.

Escape code 

c = r'\t\rasa'    #r은 Escape Codes 혹은 Escape Sequence
c
cc = '\t\rasa'
cc

>>> c = r'\t\rasa'    #r은 Escape Codes 혹은 Escape Sequence
>>> c
'\\t\\rasa'
>>> cc = '\t\rasa'
>>> cc
'\t\rasa'

 


INDEXING   

문자열 indexing

>>> a = '문근영'    
>>> a[0]
'문'
>>> a[:2]
'문근'

dir(a) # 을 수행하면

>>> dir(a)
['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__getstate__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'as_integer_ratio', 'bit_count', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']

 

__getitem__
__len__

이 존재. 

 

set indexing  -> 안 됨 

d = {1,2,3}   #set은 indexing이 안 된다.
d[0]

>>> d[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'set' object is not subscriptable

 

set은 hetero이기는 하지만, 제약 조건이 있다. 
- 순서와 중복이 없다

- 우리가 임의로 순서를 정할 수 없다. 

 

>>> {1,24,1,1,3,2,3,4,23,2,2} 
{1, 2, 3, 4, 23, 24}   # 중복을 제거하고 오름차순으로 정렬됨. 

 

 

list indexing 

c = [1,'2']  #hetetro : 서로 다른 데이터 타입
c[0] # indexing이 가능하므로 sequence type

>>> c[0]


재할당

 

a = 1
a = b = 1
b = 3
a  # immutable 하기 때문에 a 값은 바뀌지 않는다.

>>> a
1

c = d = [1,2,3]
c[0] = 100
d

>>> d
[100, 2, 3]

a = 1
a = b = 1
a,b=1,2
x,*y= 1,2,3
a +=1
global, nonlocal

 

할당 (re)bind

a=3
a=2  #이미 선언된 이름의 값을 변뎡하는 것 = 재할당
재할당을 하면, 메모리 값이 바뀐다.
즉, is 는 메모리의 일치 여부까지 판단해준다. 

OPERATOR

operatoroverloading 데이터 타입에 따라서 연산의 기능 정의

 

(1,2,3)+(4,5,6)
3*'abc'
3*[1,2,3]
(1,2,3)+(4,5,)

>>> (1,2,3)+(4,5,6)
(1, 2, 3, 4, 5, 6)
>>> 3*'abc'
'abcabcabc'
>>> 3*[1,2,3]
[1, 2, 3, 1, 2, 3, 1, 2, 3]
>>> (1,2,3)+(4,5,)
(1, 2, 3, 4, 5)
>>>

 

 

연산자

10//3 #몫을 나타내는 연산자
10/3 #그냥 나누기
10%3  # 나머지 연산자
 
10// -3 #음수로 나누면 결과도 음수. 근데 왜 4? -> 상용로그 (정수부와 소수부)
10 % -3
 
-10 / 3
-10 // 3
-10 % 3  #양수로 나누면 나머지는 양수.
 
2**3
2*2*2
# 위 둘이 실질적으로는 같지만, 내부적으로는 다르다.
#속도체크 해보자  -> 속도가 다르다.
import timeit
%timeit 2**3
%timeit 2*2*2

### 연산자에도 우선순위가 존재 한다 ###

x = 1
x.__dir__()
1.__dir__() #1.을 소수로 인식해서 에러 남.
(1).__dir__() #괄호를 주면 작동
1 .__dir__() #한 칸 띄어쓰기를 해줘도 작동.
a = 3
b = 4
a & b # bit 연산자 and : 0이 나오는 이유??
bin(3)
bin(4)

a|b  #bit 연산자 or
a ^ b
~a
a = {1,2,3}
b={2,4}
a|b  # 합집합
a&b # 차집합
a ^ b #대칭차집합
 
x = np.array([1,2,3])
x@x  # 행렬 곱

 

비교 연산자

문자는 숫자 형태로 바꿔서 비교.
'a' <'A'
ASCII CODE 대로 바꾸기

'a'<'AA' # sequence 타입은 무조건 첫 번째것만 비교
[1,2,3,4,5] > [1,100]

# 순서가 없는 건 어떻게 비교할까?
{1,2,3} > {4,5,6}
{1,2,3} < {4,5,6}
# -> 순서가 없기 때문에 어떤게 더 큰지 비교할 수 없다. 그래서 둘 다 false가 나옴.
# 다만, 동등한지는 비교해 알 수 있다.
{1,2,3}=={1,3,2}

존재론적 관점에서 조건문 체크 -> 없으면 거짓, 있으면 참. 

 

 

조건연산자

None or 4
'' or 4
{} and 3  #true false 를 반환하지 않는다. Truthy Falsy

4 or 3 / 0 #뒤에건 확인을 안 하기 때문에 뒤에서 오류가 날 수 있음.

1 or 2 or 3  # 뒤에건 확인을 안 해서 여러개 써도 의미 없음.

a=1
a in [1,2,3]   # 흔히 생각하는 or의 개념으로 확인하고 싶을 때 방법 -> in 사용
a not in [1,2,3]  # in/not in -> membership

 

in 

help('in')
a in [1,2,'3']
'a' in [1,2,3]
1 in 'abc'  # 타입에러
'1' in 'abc'

>>> a in [1,2,'3']
True

>>> 'a' in [1,2,3]
False

>>> '1' in 'abc'
False

 

dictionary
1 in {'a':1, 'b':2}  #key만 체크함.

>>> 1 in {'a':1, 'b':2}
False

for i in {'a':1, 'b':2}:
    print(i)

>>> for i in {'a':1, 'b':2}:
...     print(i)
...
a
b

for i in 1,2,3,4,5:   # 1,2,3,4,5는 괄호가 생략된 튜플이기때문에 ok
    print(i)

>>> for i in 1,2,3,4,5:  
...     print(i)
...
1
2
3
4
5

 

2 in 1

>>> 2 in 1 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: argument of type 'int' is not iterable

 

즉, in 다음에는 iterable한 것이 와야 함. 


argument 와 parameter의 차이?

def x(t):   #parameter : t
    print(t)  
x(3) #argument
operator > method

class A:
    def __add__(self, x):
        return '집에가고싶다'

a = A()

a+3
# argument는 function이나 method에 사용하는건데, 연산자가 나오는 이유?
# 실제로는 method가 실행되는 것임.

 

 

 

'Phython' 카테고리의 다른 글

함수 / * ,** / 함수 설명 보기 / 예외처리 (else, as, from, with)  (0) 2023.09.05
DBMS / ORM 시작  (2) 2023.09.05