블로그 이미지
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은...쓸수록 귀요미인듯 =_=;;;
,
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 호출이 한줄 더 들어가는정도?) 참고하자~~~
,
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() 이 호출된다. ^^;
스크립트 언어의 위대함이랄까...;;;
,
TOTAL TODAY