블로그 이미지
kalstein

여러가지 프로그래밍 관련이나...신변잡기적인 글들을 남기는 블로그입니다. 지식은 나누는만큼 강력해집니다 ^^

Rss feed Tistory
Programming/Python 2017. 11. 29. 10:50

사내에서 pip install 사용하기

windows에서 쓸때.


set http_proxy=168.219.61.252:8080
set https_proxy=168.219.61.252:8080

python -m pip install --trusted-host pypi.python.org [pkgname]


하면 진행가능.

Programming/Python 2011. 6. 1. 10:28

Python 느님의 위엄. callback 함수 작성이 너무도 쉽다!

C/C++에서는 callback 함수 한번 작성하려면 상당히도 귀찮다.
대표적인 callback 함수 쓰는게 sort() 라고 볼수있다. (STL에서는 for_each도 있고)
(callback 함수라기보다는 임시함수라고 하자. 그게 더 맞는 표현이니...ㅋ)

간단히 표현하자면, 함수호출시 인자값으로 함수포인터를 넘겨주는건데...
이게 좀 code reading 상 불편한 점이 있다. 왜냐고?

func_A (int i)
{ .... }
func_B(callback_func func)
{
    func(10);
}
main_func()
{
    func_B(func_A);
}

보통 이런 구조가 되는거다.
그러면, main_func을 읽고있다가 func_B 를 호출하는걸 알았다.
근데 func_A는 또 뭐야? 뭘 어떻게 비교하는거지?

이런 불편함때문에 boost lambda라는것도 있다.
저런 함수들은 보통 사이즈가 작고 구문도 간단한 경우가 많다.
그래서 람다 함수로 작성하면 func_A 같은걸 따로 작성하지않을 수 있고
코드 리딩도 쉬워진다.

반면, 복잡한 함수라면? 조금 까다로워진다.
어려운 람다함수를 쓰느니 그냥 func_A를 쓰는게 더 나을수있다는것.
자 그러면 python에서는 어떨까. nested function 선언이 가능하다!

>>> def outer():
       x
= 1
       
def inner():
           
nonlocal x
           x
= 2
           
print("inner:", x)
       inner
()
       
print("outer:", x)


>>> outer()
inner
: 2
outer
: 2

특히나, "nonlocal" 키워드를 통해서, 일반 function과의 변수를 공유할수도 있다.
(공유하기 싫으면 "nonlocal x" 만 지워버리면 된다. 그럴경우 outer의 x와 inner의 x는 전혀 별개의 변수)
정말 python은...쓸수록 귀요미인듯 =_=;;;
  • rein 2011.06.07 15:55 ADDR 수정/삭제 답글

    C++에도 비슷한 기능이 추가되었습니다 (C++ 11 a.k.a C++ 0x).
    최근에 나온 컴파일러들 (ICC 11, GCC 4.5+, VS 2010)에도 들어가 있는 기능인데요, 저 비슷하게,

    sort(v.begin(), v.end(), [=](const int &a, const int& b) { return a< b;}); 하는 식으로 익명함수를 단축해서 쓸 수 있습니다. 표준에 맞게 구현된 STL 컨테이너/알고리즘이나, TBB parallel_? 류에서도 그냥 쓸 수 있게 되어있습니다.

  • rein 2011.06.07 15:55 ADDR 수정/삭제 답글

    저도 예~~전에는 boost::function 써서 클로져 비슷한거 만들어 썼는데, VS 2010에서 짜는 코드베이스는 전부 C++ 0x lambda를 쓰는 형식으로 바꿨습니다

    • kalstein 2011.06.13 16:57 신고 수정/삭제

      오...

      C++은 더이상 뭘 얼마나 더 붙일까요 ㅋㅋㅋ
      조만간 스크립트 언어도 진출할기세? ^^;

Programming/Python 2009. 1. 25. 15:01

WINAPI를 python에서 호출하기.

뭐 ctypes 매뉴얼에 잘 나와있긴한데...
왠만한 winapi들은 python win32 expansion에 들어있다. 그런데 가끔은 없는것도 있단말이지.
그럴경우는 kernel32.dll에 있는 함수를 직접 호출해줘야한다.
하는 방법은 매우 간단하다.
(FindFirstVolume이라는 winapi 호출을 한다고 가정한다)

from ctypes import *
winapifunc = windll.kernel32.FindFirstVolumeA

그리고는 winapifunc 함수호출. 끝.
-ㅁ-;; 좀 허전하지? ㅎㅎ 여기서 반드시 주의할점. 대부분의 windows api들은 A,W로 끝나는 ANSI, Unicode 버젼이 따로 존재한다. 즉, 실제 함수명과 MSDN에 나오는 함수명은 다른것. 실제 함수명을 보고싶다...면 DLL export 가 어떻게 되어있는지 살펴보면 좋다.

http://www.nirsoft.net/utils/dll_export_viewer.html

여기 가보면 해당 유틸리티를 다운받을수 있다. 이건 꼭 kernel32.dll뿐만 아니라 다른 dll들에도 적용되므로 (다른점이라면 LoadLibrary 호출이 한줄 더 들어가는정도?) 참고하자~~~
dll, Python, WinAPI
Programming/Python 2008. 12. 30. 12:31

Python에서 동적(?) 함수 호출

요즘 python을 개인적으로 관심있게 보고있는데...한가지 의문이 생겼더랜다.

'스크립트 언어지만, 실제 .py 코드가 동작하는것은 이미 쓰여진 코드. 그러면 runtime에 코드를 동적으로 생성해서 실행하는것이 가능할까?'

자세히는 보지않아서 정확한 구현을 어떻게 하는지는 기억이 나지는 않지만, C/C++쪽에서도 실시간으로 op code를 만들 수 있다. 비단 C/C++뿐만 아니라 .NET 환경하에서도 가능하다. (예전 windows들도 상당히 즐겨썼다고 한다. asm을 만들어서 끼워넣는 방법. Beautiful code 라는 책에서 살펴볼 수 있다)
그렇다면 python은??

일단 함수,클래스 들의 호출은 kldp에 문의해서 알아봤다 ㅎㅎ (링크)

__dict__ 를 사용하면 될꺼같은데요.
만약 인터프레터에서 나가고 싶으면 exit() 을 처도 되지만,
__buitlins__.__dict__["exit"]() 을 처도 나가집니다. ㅎㅎ.
다른 예로...

>>> class Foo:
... def bar(self):
... print "Hello, world"
...
>>> a = Foo()
>>> a.bar()
Hello, world
>>> Foo.__dict__
{'__module__': '__main__', 'bar': , '__doc__': None}
>>> Foo.bar(a)
Hello, world
>>> Foo.__dict__['bar'](a)
Hello, world
>>>

이 코드에선 a.bar(), Foo.bar(a), 와 Foo.__dict__['bar'](a) 가 다 같은 뜻을 가집니다 ㅎㅎ. 만약 문자열을 가지고 함수를 부르고 싶으면 __dict__['문자열'] 을 해버리면 되겟군요.

오호라...역시 되는구나.
그렇다면 조금 다른 활용을 살펴보도록 하자. 보통 OOP에서의 동적 함수 호출이라고 하면 C++로 표현해서 다음과 같은걸 의미한다.

class Base
{    virtual void foo() = 0; };

class Derived_1
{    virtual void foo() { 어쩌구; } };

class Derived_2
{    virtual void foo() { 저쩌구; } };

그리고는 실제 호출시에는 Base의 포인터만을 이용해서 호출하는 방식. 이방식의 문제점이라면...Factory Pattern을 쓴다고 했을때, type별로 매칭되는 뭔가를 따로 만들어줘야 한다는거지. id라고나 할까? id가 1이면 Derived_1을 생성해주고, 2이면 Derived_2를 생성해주고.

자 예제 코드 --->>
Base * FactoryMethod(int class_id)
{
    if (1 == id)
        return new Derived_1();
    else if (2 == id)
        return new Derived_2();
    else
        return NULL;
}

요런식으로 된다. 그런데...그냥 따로 id 받지않고 클래스 명을 받을수도 있지않을까? 또 코드로 말하자면 --->>
Base * FactoryMethod(const string class_name)
{    return new class_name(); }

이렇게 말이다. 좀 어이없을수도...;; C/C++에선 쉽지않을꺼다. (가능할까? 흠...잘 모르겠네...;;) 그런데 python은 저게 된다 -_-;;;; 컴파일을 인터프리터로 할 수 있기때문에 가능하다. 아래의 코드.

-------------------------------------------------------------
import codeop

class T1:
    def Eval(self, val):
        print val

class T2:
    def Eval(self, val):
        print 2 * val

tmpcodeobj = codeop.compile_command('obj = T1()')
eval(tmpcodeobj)
obj.Eval(10)
-------------------------------------------------------------

위의 코드에서 'obj=T2()' 이렇게 문자열을 바꾸면 T2:Eval() 이 호출된다. ^^;
스크립트 언어의 위대함이랄까...;;;
  • 냐궁 2008.12.31 14:00 ADDR 수정/삭제 답글

    Base * FactoryMethod(const string class_name)
    { return new class_name(); }

    요 코드 자체는 어렵겠지만...

    너가 위에 적은

    Base * FactoryMethod(int class_id)
    {
    if (1 == id)
    return new Derived_1();
    else if (2 == id)
    return new Derived_2();
    else
    return NULL;
    }

    요걸 좀 고쳐서 클래스 이름으로 동적 생성하는건 많이 쓰인다는...
    실제로 win32api / MFC 등에서 인스턴스를 생성하는 Create 함수에서 클래스명을 받는
    부분들이 있고.. 좀더 복잡하게는 COM/ATL등도 그런식으로 동작하는거지 모....

    그리고 .NET에서는 Assembly라는게 있어서..
    클래스 이름으로 인스턴스를 동적 생성하는게 되는듯..? (하기사 모든 리소스를 관리하는 가비지 콜렉터가 있다면 그놈이 조금만 더 해주면 어렵지 않을듯..)

    그나저나 새해 복 많이 받으삼~

    • kalstein 2009.01.02 09:19 신고 수정/삭제

      클래스명으로 생성하는거...물론 가능한뎁 ㅋ 쓸까하다가 귀찮아서 안썼지만. map<> 이라던가 써서 클래스명(string) 클래스를 등록해두면 생성하는게 가능하지. 다만 추가적인 뭔가가 필요한거잖여~~

      COM쪽도 실질적으로는 클래스id (uuid라던가?) 를 통해서 생성하는거고...뭔가 associate한 자료가 없고 실제 클래스명만 가지고는 생성이 쉽지않다는거지. (닷넷쪽은 가능할꺼같긴한데...잘 모르겠네.)

      형두 새해복 많이 받으3~~~ ^^

TOTAL 38,593 TODAY 3