Python/Underscores2019. 1. 29. 16:35

Python 에서 언더스코어는 5가지 사용법으로 구분된다


Single Underscore:

  • In Interpreter
  • After a name
  • Before a name

Double Underscore:

  • __leading_double_underscore
  • __before_after__


언더스코어가 독립적으로 사용되는 경우
파이썬 프롬프트(인터프리터) 상에서 가장 마지막에 실행된 표현식의 값을 가진 변수로 사용된다

D:\PythonProjects>python
Python 3.7.2 (tags/v3.7.2:9a3ffc0492, Dec 23 2018, 22:20:52) [MSC v.1916 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> 1+2
3
>>> _
3
>>> _ * 2
6
>>> _ += 4
>>> _
10
>>>



다음은 위와 같이, 파이썬 프롬프트에서 _ 기호가 변수로 사용되는 경우이다

추출된 값을 굳이 사용할 필요가 없는 경우에 그 값을 무시하는 의도


# 아래의 문장은 0 ~ 4까지 화면에 표시한다

for x in range(5):

    print(x)


# 아래의 문장도 위와 동일한 결과를 표시한다

for _ in range(5):

    print(_)


# 아래의 문장은 0 ~4까지의 숫자가 필요한 것이 아니라 5번 루프를 실행할 목적으로 사용된다

for _ in range(5):

    print("Hello")



def test():

  return (3,5,2,1)     # Tuple을 리턴하는 함수


print( test() )

a, b, _, _ = test()     # 리턴된 튜플의 두번째 값 까지만 필요한 경우

print(f"a:{a}, b:{b}")



이름 뒤에 _ 가 붙는 경우 (예약어는 변수명으로 사용할 수 없으므로 이름 뒤에 _를 붙인 경우)

class Product:

  def __init__(self):

    self.name = "Galaxy 10"

  


def printClsName(class_):    # class라는 변수명을 사용하고자 하지만 Python 예약어라서 안됨

    print(class_)


p1 = Product()

printClsName(p1.__class__)    # <class '__main__.Product'>



함수이름 왼쪽에 _가 붙는 경우

보안성이 약한 private 의미로 사용하는 경우, 함수이름 왼쪽에 _붙이면 다른 파일에서 from file_name import * 방법을 사용하여 가져올 때 해당 함수는 누락되어 사용할 수가 없게 된다

util.py

def func1():

    print("public function")


def _func2():

    print("private function")


위의 util.py 파일을 다른 파일에서 사용하는 경우 ( _func2() 함수는 정의되지 않은 함수라는 오류 발생 )

from util import *


func1()

_func2()


위의 오류는 다음과 같은 방법으로 해결된다

import util


util.func1()

util._func2()



더블 언더스코어를 변수 왼쪽에 붙인 경우(Mangling)

Product.py ( __price 변수는 선언된 클래스에서 그 이름으로 사용가능하지만 외부에서는 안됨)

class Product:

  def __init__(self):

    self.name = "Galaxy 10"

    self.__price = 300


  def print_info(self):

      print(f"name:{self.name}")

      print(f"price:{self.__price}")


위의 클래스를 외부에서 사용하면서 __price 변수에 직접 접근하는 경우에 오류가 발생한다. 더블언더스코어가 2개 붙은 변수는 인터프리터에서 변수 이름을 고칠 때 _클래스명__변수명 형식으로 변경하기 때문이다. 이런 작업을 Mangling(맹글링)이라고 한다

import Product as p


p1 = p.Product()

#print( p1.__price)                  # 오류


print( p1._Product__price)        # 정상

p1.print_info()                       # 정상



__이름__ 형식의 함수/변수

인터프리터에 내장된 특수한 함수/변수를 나타낸다

__init__() 생성자 함수가 여기에 속한다

또한 클래스 안에 정의할 수 있는 가감승제 메소드( __add__(), __sub__(), __mul__(), __divmod__() 등)도 있다. 이들 함수가 클래스에 정의되어 있으면  obj.__add__(2,3) 형식으로 호출할 수 도 있고 수학의 덧셈식( obj1 + obj2)형식으로도 호출할 수 있기 때문에 연산자 오버로드용으로 사용할 수 있다



__add__() 함수를 정의하여 벡터 덧셈을 직관적으로 표현한 경우(연산자 오버로드)

class vector:


  def __init__(self, x,y,z):

    self.x = x

    self.y = y

    self.z = z


  def __add__(self, other):

    x_ = self.x + other.x

    y_ = self.y + other.y

    z_ = self.z + other.z

    return vector(x_,y_,z_)


  def print_info(self):

    print(f"x:{self.x}, y:{self.y}, z:{self.z}")


v1 = vector(1,2,3)

v2 = vector(4,5,6)

v3 = v1 + v2

v3.print_info()     #  x:5, y:7, z:9



Weak Private, Strong Private

class UnderscoreTest:
def __init__(self, val1, val2):
self._val1 = val1 # Weak Private
self.__val2 = val2 # Strong Private
def print_dict(self) :
print(self.__dict__)

u = UnderscoreTest(100, 200)
u.print_dict() # {'_val1': 100, '_UnderscoreTest__val2': 200}
print(u._val1)
#print(u.__val2) # 오류:__val2 변수가 선언되지 않음
#print(u.val1) # 오류:val1 변수가 선언되지 않음
print( u._UnderscoreTest__val2 )


Setter, Getter에서는 싱글 언더스코어, 더블 언더스코어 모두 사용할 수 있고 심지어 3개 이상도 가능하다

변수 왼쪽에 언더스코어를 2개이상 사용하면 Mangling 이 적용된다

class UnderscoreTest:
def __init__(self, val1, val2):
self.val1 = val1 # Weak Private
self.val2 = val2 # Strong Private
@property
def val1(self):
print("val1 getter")
return self._val1

@val1.setter
def val1(self, v):
print("val1 setter")
self._val1 = v

@property
def val2(self):
print("val2 getter")
return self.__val2

@val2.setter
def val2(self, v):
print("val2 setter")
self.__val2 = v

def print_dict(self) :
print(self.__dict__)

u = UnderscoreTest(100, 200) # val1 setter, val2 setter 호출
u.print_dict() # {'_val1': 100, '_UnderscoreTest__val2': 200}
print(u.val1) # val1 getter 호출
#print(u.__val2) # 오류:__val2 변수가 선언되지 않음(Mangling)
print(u._val1) # _val1에 직접접근, val1 setter호출 안됨
print( u._UnderscoreTest__val2 ) # Mangling 효과, _UnderscoreTest__val2에 직접접근


Posted by cwisky
PHP/Time2019. 1. 23. 23:33

<?php

// 시간 문자열을 날짜 객체로 변환

$date = new DateTime('2019-01-23 12:30:23');


// 날짜 객체를 시간 문자열로 변환

echo $date->format('Y-m-d H:i:s');


// 현재 로컬시간 구하기

date_default_timezone_set("Asia/Seoul");

echo date('Y-m-d H:i:s'); //로컬시간을 문자열로 리턴


Posted by cwisky
PHP/CI AJAX2019. 1. 22. 16:45

CodeIgniter에서 AJAX 사용하기


사원번호를 클릭할 때마다 jQuery를 이용한 AJAX 요청이 CodeIgniter에 전달되면 콘트롤러와 모델, 뷰 컴포넌트를 거쳐 사원정보를 JSON 포맷으로 응답한다

응답을 수신한 success 함수는 JSON 오브젝트를 사용하여 각 데이터가 표시될 위치에 출력하는 예이다


실행환경

웹서버 상의 CodeIgniter 루트에 css, js  등의 리소스 폴더를 생성하고 css 폴더에는 스타일시트 파일을 저장하고 js 폴더에는 jQuery.min.js  등의 자바스크립트 파일을 복사해둔다


emp 테이블

 - empno INT                # 사번

 - ename VARCHAR(20)   # 이름

 - dname VARCHAR(20)   # 부서

 - sal INT                      # 급여

 - pic VARCHAR(20)        # 사진파일명



웹서버의 폴더 구조

- www : 웹서버 루트 폴더

   - ciBoard 폴더 : CodeIgniter 구성파일 저장

      - css : css 파일 저장

      - js : jQuery 파일 저장

      -application/controllers/Emp.php

      -application/models/EmpModel.php

      -application/views/emp.html, emp_json.php



콘트롤러 생성

ciBoard/application/controllers/Emp.php  (요청 url : http://localhost/ciBoard/emp )

<?php  

 defined('BASEPATH') OR exit('No direct script access allowed');


 class Emp extends CI_Controller 

 {  

    public function __construct() {

         parent::__construct();

         $this->load->helper('url');

    }

    

    public function index() {

        $this->load->view("emp.html");  

    }


    function getInfo($num) {

        $this->load->model('EmpModel');

        $data = $this->EmpModel->getInfo($num);

        $row = array('row'=>($data->row_array()));

        $this->load->view('emp_json', $row);

    }

 }



모델 클래스 생성

ciBoard/application/models/EmpModel.php

<?php  

 defined('BASEPATH') OR exit('No direct script access allowed');

 

 class EmpModel extends CI_Model

 {

     public function __construct() {

         parent::__construct();

     }

     

     public function getInfo($num)

     {

         $sql = "SELECT * FROM emp WHERE empno=$num ";

         $result = $this->db->query( $sql );

         return $result;

     }

 }


뷰 파일

ciBoard/application/views/emp.html (요청 url : http://localhost/ciBoard/emp )

<!DOCTYPE html>

<html>

    <head>

        <title>사원정보 페이지</title>

        <meta charset="UTF-8">

        <meta name="viewport" content="width=device-width, initial-scale=1.0">

        <script src="js/jquery-3.3.1.min.js"></script>

        <script>

            $(function(){

              alert('jQuery Ready!');

            });

            function requestEmpInfo(num) {

                $.ajax({

                    url : '<?php echo base_url();?>emp/getinfo/'+num,

                    method: 'post',

                    data: { 'num' : num},

                    dataType : 'json',

                    success : function(res) {

                        //alert(res.ename);

                        $('#ename').html(res.ename);

                        $('#empno').html(res.empno);

                        $('#dname').html(res.dname);

                        $('#sal').html(res.sal);

                        $('#pic').html('<img src=\'images/'+res.pic+'\'>');

                    },

                    error: function(xhr, status, error){

                        console.log(xhr.status + ', '+xhr.responseText +', '+status+', '+error);

                        alert(status);

                    }

                });

            }

        </script>

        <style>

            img { width: 200px; height:200px; }

        </style>

    </head>

    <body>

        <h3>사원정보</h3>

        <div>이름 : <span id="ename"></span></div>

        <div>번호 : <span id="empno"></span></div>

        <div>부서 : <span id="dname"></span></div>

        <div>급여 : <span id="sal"></span></div>

        <div>사진 : <span id="pic"></span></div>

        <div>

            [<a href="javascript:requestEmpInfo(11);">11</a>]

            [<a href="javascript:requestEmpInfo(12);">12</a>]

            [<a href="javascript:requestEmpInfo(13);">13</a>]

            [<a href="javascript:requestEmpInfo(14);">14</a>]

            [<a href="javascript:requestEmpInfo(15);">15</a>]

        </div>

    </body>

</html>




JSON 문자열을 웹브라우저에 출력하는 뷰 콤포넌트

ciBoard/application/views/emp_json.php

<?php

echo json_encode($row);


Posted by cwisky