분류없음2009.12.08 22:39

파이썬에서 XMLRPC CGI 서버가동하기

다음은 CGI HTTP 서버스크립트 임 /cgi-bin , /wbin 디렉토리는 CGI 가 실행되는 디렉토리로 서버가 실행되는 스크립트의 디렉토리에 밑에 있다. (httpsrv.py)

from  http.server import *
from http.server import CGIHTTPRequestHandler

def run(server_class=HTTPServer, handler_class=CGIHTTPRequestHandler ):
server_address = ('', 8080 )
handler_class.cgi_directories = ['/cgi-bin', '/wbin']
httpd = server_class(server_address, handler_class)
httpd.serve_forever()

run()

XMLRPC CGI 스크립트 ( cx1.py ):

from xmlrpc.server import DocCGIXMLRPCRequestHandler

class MyFuncs:
def div(self, x, y) : return x // y

handler = DocCGIXMLRPCRequestHandler()
handler.register_function(pow)
handler.register_function(lambda x,y: x+y, 'add')
handler.register_introspection_functions()
handler.register_instance(MyFuncs())
handler.handle_request()

XMLRPC CGI 테스트 스크립트 ( cx1c.py ):

import xmlrpc.client

s = xmlrpc.client.ServerProxy('http://localhost:8080/wbin/cx1.py' )

print(s.pow(2,3)) # Returns 2**3 = 8
print(s.add(2,3)) # Returns 5

# Print list of available methods
print(s.system.listMethods())

이제 서버를 가동하고 테스트 실행하면:

python  httpsrv.py
..
python cx1c.py

다음과 같은 결과를 얻을 것이다.:

>python cx1c.py
8
5
['add', 'div', 'pow', 'system.listMethods', 'system.methodHelp', 'system.methodS
ignature']

자바스크립트와 XMLRPC

다음은 자바스크립트에서 직접 XML 사용하여 XMLRPC를 호출하는 방법이다. 이 방법은 번거롭고 리턴받은 XML 코드도 해석하여야 사용가능하다.

<html>

<body>
<a href= "/cgi-bin/cx1.py">ii</a>
<script language="javascript" type="text/javascript">

var req = new XMLHttpRequest();
req.open('POST', 'http://localhost:8080/cgi-bin/cx1.py', false );
req.send(
"<?xml version='1.0'?>" +
"<methodCall>" +
"<methodName>add</methodName>" +
"<params>"+
"<param><value><i4>23</i4></value></param>" +
"<param><value><i4>23</i4></value></param>" +
"</params>" +
"</methodCall>"
);
document.write( req.responseText + "--------")

</script>

</body>
</html>

mimic.js 자바스크립트 XML-RPC 라이브러리

파이썬과 javascript 사이의 XML-RPC 에서 잘 동작하는 라이브러리로 mimic.js 이 있다.

위 mimic.js 를 다운로드 하고 다음과 같이 자바스크립트를 작성하면

<html xmlns="http://www.w3.org/1999/xhtml">

<head>
<script type="text/javascript" src='mimic.js' > </script>
</head>

<body>
<script type="text/javascript" >

a = new XmlRpcRequest( 'cgi-bin/cx1.py','add')

a.params= [ 30 , 12345 ]

//또는
// a.addParam( 30 )
// a.addParam( 12345 )

b = a.send()

document.write( "`30 + 12345 = ` 의 결과는 => " )
document.write( b.parseXML() )

</script>

</body>

</html>

위 html 을 브라우저 로 보아 다음과 같이 결과가 보인 다면 성공적으로 작동되고 있는 것이다.


신고
Posted by 콩이랑 팥이랑 심자꾸나
플밍/python2009.08.14 20:36

보통 파이썬에서 람다는 한줄짜리 아름없는 함수로 알려져 있다.
map , reduce , 등의 함수와 함께 유용하게 사용될 수 있으나 복잡한 연산을 하기 어렵다는 결점을 가지고 있다.

다음 파이썬 문법을 보아도 중간의 문장없이 인수와 리턴문으로만 구성되어 있음이 명확하다 .
def <lambda>(arguments): return expression


그러나 여러가지로  시도해 본 결과 람다문을 중복하여 사용하거나 or , and 로 분기하는 등 다양하게 활용될수 있었다.
( 테스트는 python 3.1 )


# 2009. 8 ... <.)++++<  budl


#행렬바꾸기 #############################################



import random

# 예제는 random 로 랜덤한 수와 그 수에 10을 더한 값을 리턴하는 인수없는 함수를 만드는 것이다.
# random 에서 exec 로 연산하기 
b = lambda :( exec('x=random.randint(1,100);y=x+10',globals()) ) or ( x , y )

print()

A=[]
for N in range(0,10)  :
    B = []
    for x in range(*b()) :
        B.append( x )
    A.append(B)
    print ( B )


Z = zip( *A  )
for x in Z : print(x)   



# 람다 중복하기  #############3333333333333
# 위 exec 를 사용하는 대신 다음과 같이 중복람다를 쓰면 보다 간단하다.

c = lambda :( lambda x=random.randint(1,100) :( x , x +10 ))()

print( c() )
print( c() )
print( c() )
print( c() )
print( c() )
print( c() )


z=100
c = lambda x :( lambda i=x , j=z :( "{}+{}+{}+{}".format(i,j,z,x), " => " , i+j+z+x ) )()
print( *c(18) )


#차라리 이렇게 할 바에 함수를 하나 정의하지
#삼중중복 람다
x = lambda : \

        (lambda a=100 , b=26 : \
            (lambda i=a+a , j=b*b : ( i , j )  \
            )()   \
        )()

print( x())


#차라리 이렇게 할 바에 함수를 하나 정의하지
#조건에 따른 분기
q = lambda x, y : ( x%10 and 'x%10'  ) or ( y%10 and 'y%10' ) or ((x//y)%10 and '(x//y)%10')

print ( q(20,10) )


신고
Posted by 콩이랑 팥이랑 심자꾸나
플밍/python2009.08.12 12:16
python에서  inspect  모듈을 사용하는 것은 디버깅을 할때 특히 유용하게 사용될수 있다.

단순히 소스의 실행위치의 라인번호를 찍는 것은 sys 모듈을 사용할 수도 있다.

예제는 소스코드의 실행되는 위치의 정보를 보여주는 예제 
 
import sys

def traceit(frame, event, arg):

    '''
    call line return exception
   
    dir( frame )
    ['__class__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__get
attribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__ne__', '_
_new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__',
 '__str__', '__subclasshook__', 'f_back', 'f_builtins', 'f_code', 'f_globals', '
f_lasti', 'f_lineno', 'f_locals', 'f_trace']

    '''
    if event == "return":
        lineno = frame.f_lineno
        print( '=' * 79 )
        print ( "line ==> ", lineno  )
        print ( "arg ==> ", arg )
       
        for x in [ 'f_back', 'f_builtins', 'f_code', 'f_globals', 'f_lasti', 'f_lineno', 'f_locals', 'f_trace' ] :
            print(  x , eval( "frame.{0:}".format( x )  ) , sep=' ==> ')
            print( '=' * 79 )
           
    return traceit

def main( *arg ):
    m=[1,2,3,4]
    print ( "\n\n\nIn main" )
    for i in range(5):
        print ( i, i*3 )
    print ( "Done." )
   
    return 1000
   

sys.settrace(traceit)
main( 1,7812 ,['한글'])





inspect 모듈을 사용하면 보다 손쉽게 함수를 호출하는 곳의 위치와  프레임을 찾을 수 있다. 
 

다음은 inspect 을 사용한 예제임 ( python 3.1 에서 테스트 되었음 )

디버깅을 위해서 -d 옵션을 사용하여 pdb 모드로 테스트 할수 있습니다.
>python  inspect_sample.py -d

pdbx.py 
import pdb , sys

print ( sys.argv )
if '-d' in sys.argv : pdb.set_trace()

inspect_sample.py
import inspect
import pdbx

def 어디야 ():

    print( '==>  ' , end='\n' )

    print ( *inspect.stack() , sep='\n\n'  , end='-'*50 + '\n')   

    outer1 = inspect.stack()[1][0]
    outer2 = inspect.stack()[2][0]
   
    print ( '-->>  ' , inspect.currentframe() )
   
    print ( 'F0 줄번호 :' , inspect.getlineno(inspect.currentframe())  )  
    print ( 'F1 줄번호 :' , inspect.getlineno(outer1 )  )  
    print ( 'F2 줄번호 :' , inspect.getlineno(outer2 )  )  
   
    # f_locals을 통해서 상위 프레임의 지역변수를 본다
    a = outer1.f_locals['x'] + outer1.f_locals['y']
    return a
   
def 여기야():

    x = 1
    y = 2

    print ( 어디야 () )

   
여기야()

여기야()

여기야()




다음은
http://bbs.python.or.kr/viewtopic.php?t=21471

에 소개된 inspect 예제를 python3.1에 맞게 고친것이다.
import pdbx
import types
import inspect

def countcall(func):
    def countwrap(*args, **kwargs):
        countwrap.count += 1
        return func(*args, **kwargs)
    countwrap.count = 0
    return countwrap

#클래스 함수를 변경한다.
def countallmethods():
    uframe = inspect.stack()[1][0]
   
    #문제있음
    print( uframe.f_locals )
   
    for name, obj in uframe.f_locals.items():
       
        #if callable(obj):
        #if hasattr(obj, "__call__") :
       
        #python 3.1 에서는 다음과 같이 타입을 비교한다.
        if (type(obj) == types.FunctionType ) :

            print ( "= = =" , name )
            print( "Wrapping", name)
            uframe.f_locals[name] = countcall(obj)

class OldClass:
    def gogo(self):
        print( "gogo!!")
    def hehe(self):
        print( "hehe!!")
    def merong(self):
        print( "merong!!")

    countallmethods()

OldClass().gogo()
OldClass().hehe()
OldClass().merong()
OldClass().hehe()
OldClass().gogo()
OldClass().merong()
OldClass().merong()
OldClass().merong()
OldClass().merong()

print( "called gogo", OldClass.gogo.count)
print( "called hehe", OldClass.hehe.count)
print( "called merong", OldClass.merong.count )




== 참고 ==

  * Tracing python code

  * PyMOTW: inspect



신고
Posted by 콩이랑 팥이랑 심자꾸나