레이블이 python인 게시물을 표시합니다. 모든 게시물 표시
레이블이 python인 게시물을 표시합니다. 모든 게시물 표시

2018년 6월 20일 수요일

[Link] Python 개인 정리

Python 공부하면서 개인적으로 몰랐던 부분을 정리..


점프 투 파이썬
 : https://wikidocs.net/book/1

사이트를 참고하였음.



** 제곱연산자
: https://wikidocs.net/12#x-y


문자열 formatting
https://wikidocs.net/13#format

>>> "I eat {0} apples".format(3) 'I eat 3 apples'

>>> number = 10 >>> day = "three" >>> "I ate {0} apples. so I was sick for {1} days.".format(number, day) 'I ate 10 apples. so I was sick for three days.'


Container
- list [,]
 : https://wikidocs.net/14#_7
 : append, pop/delete/remove
- dict {:}
 : https://wikidocs.net/16#_6
 : [], get, del
 : keys, values
- tuple (,)
- set {,}


list slicing
https://wikidocs.net/14#_4

>>> a = [1, 2, 3, 4, 5] >>> a[0:2] [1, 2]


if
https://wikidocs.net/20#if_1

if 조건문: 수행할 문장1 수행할 문장2 ... else: 수행할 문장A 수행할 문장B ...


for
https://wikidocs.net/22#for

for 변수 in 리스트(또는 튜플, 문자열): 수행할 문장1 수행할 문장2 ...


function
https://wikidocs.net/24#_6

def 함수이름(매개변수): <수행할 문장> ... return 결과값

* ':' 다음 줄의 들여쓰기가 중요.


with
https://wikidocs.net/26#with

f = open("foo.txt", 'w') f.write("Life is too short, you need python") f.close()
를 아래와 같이 handle scope내에서 파일 처리 가능
with open("foo.txt", "w") as f: f.write("Life is too short, you need python")


class method의 첫번째 매개변수
https://wikidocs.net/28#_6




dir 내장 함수
https://wikidocs.net/32#dir


2014년 9월 17일 수요일

windows 7에서 python twisted 설치 및 echo server 실행

인사이트에서 나온 '트위스티드'를 우연찮게 빌리게 되어 봄.
http://www.insightbook.co.kr/books/programming-insight/twisted-network-programming-essentials-2
파이선이 뭔지도 제대로 모르는 상태이고 그냥 샘플만 끌적이는 것임.

[ installation for Windows 7 ]

윈도우에 트위스티드를 설치하기 위해서는 python 2.7.x 버전이 설치 되어 있어야 한다.

Windows


책에서는 python이 설치된 상태에서 위의 것이 모두 설치 되면 된다고 하는데...
Zope.Interface가 python 2.7이 없다면서 설치가 안된다.

“Python version 2.7 required, which was not found in the registry”

위 message는 "Win 7 64bit 에서 초기 파이썬 설치 시
Install just for me를 체크하지 않고 Install for all users를 선택한 사용자에게 생기는 문제"
라고
http://modular.tistory.com/34  에서 찾게 되어 python을 다시 설치 했음. :(

그 외 방법은 registery를 추가하는 방법이 있는 것 같다.
http://stackoverflow.com/questions/3652625/installing-setuptools-on-64-bit-windows

... 그냥 리눅스를 쓰는게 편할 듯...

twisted가 설치 완료되면 python shell에서 아래와 같이 확인 가능

>>> import twisted
>>> twisted.__version__
'14.0.0'



[ echo server/client example ]

제일 간단한 echo protocol 기반 서버. 하지만 echo protocol은 비록 몇줄 일지라도 RFC 문서도 존재함. 
근데 재미 있는 것은 명령 프롬프트에서 실행하면 잘 되는데 IDLE에서 실행하면 client 쪽에서 계속 connection fail이 발생한다..


[ echo server ]

from twisted.internet import protocol, reactor

class Echo(protocol.Protocol):
    def dataReceived(self, data):
        print "data received"
        self.transport.write(data)

class EchoFactory(protocol.Factory):
    def buildProtocol(self, addr):
        return Echo()

reactor.listenTCP(8888, EchoFactory())
reactor.run()


Reactor를 만들어 TCP 880 port에서 listen하고 connection이 생성 될 때 마다 EchoFactory()를 생성하여 처리하도록 하고 있음 (Reactor 개념은 ......  참조)

Reference를 찾아보니 (python은 처음이라 API reference도 좀 생소하다..)


reactor에서는 networking, threading, event dispatching등의 기능을 해야 하고 
실제 여러 platform, OS에서 동작 하여야 하므로 추상화된 API 로 동일 기능을 제공할 수 밖에 없을 것임. 예를 들어 boost.asio도 기본적인 API로 동일 functionality를 보장하고 os 특화된 기능 (overlapped i/o 같은)을 별도의 class로 떼서 제공을 하니..

reactor interfaces
IReactorCore, IReactorTime, IReactorProcess, IReactorTCP, IReactorSSL, IReactorUDP, IReactorMulticast, IReactorUNIX, IReactorUNIXDatagram, IReactorFDSet, IReactorThreads, IReactorPluggableResolver

echo 서버는 TCP 기반이므로 reactor의 TCP interface method를 구현.


MethodlistenTCPConnects a given protocol factory to the given numeric TCP/IP port.
MethodconnectTCPConnect a TCP client.
reactor의 개념 상 TCP 통신을 위해서 제공하는 API는 connection 관련 단 두개..
connection 이후 server, client 간 read/write 는 위 API의 argument로 제공되는 protocol factory 에서 처리가 된다.

def listenTCP(port, factory, backlog=50, interface=''): (source)
Connects a given protocol factory to the given numeric TCP/IP port.
Parametersporta port number on which to listen
factorytwisted.internet.protocol.ServerFactoryinstance
backlogsize of the listen queue
interfaceThe local IPv4 or IPv6 address to which to bind; defaults to '', ie all IPv4 addresses. To bind to all IPv4 and IPv6 addresses, you must call this method twice.

Server factory class는 아래 링크에서 찾아 볼 수 있고
관련된 protocol들도 명시 되어 있다.



Inherited from Factory:
Class MethodforProtocolCreate a factory for the given protocol.
MethodlogPrefixDescribe this factory for log messages.
MethoddoStartMake sure startFactory is called.
MethoddoStopMake sure stopFactory is called.
MethodstartFactoryThis will be called before I begin listening on a Port or Connector.
MethodstopFactoryThis will be called before I stop listening on all Ports/Connectors.
MethodbuildProtocolCreate an instance of a subclass of Protocol.
echo 서버의 동작(단순 read한 data를 write하여 client로 전달)은 단순하므로 buildProtocol method만 사용하여 echo client 처리를 위한 protocol instance를 생성함.


MethodlogPrefixReturn a prefix matching the class name, to identify log messages related to this protocol instance.
MethoddataReceivedCalled whenever data is received.
MethodconnectionLostCalled when the connection is shut down.
Inherited from BaseProtocol:
MethodmakeConnectionMake a connection to a transport and a server.
MethodconnectionMadeCalled when a connection is made.

참고... 예제라 base protocol을 상속하여 구현하지만 twisted내에도 echo protocol을 제공하고 있음


echo server/client의 동작을 위해
reactor->facory에서 생성된 protocol.dataReceived()에서 data를 받아
transport.write(data)를 해주어 client에 전달하면 끝..



[ echo client ]

from twisted.internet import reactor, protocol

class EchoClient(protocol.Protocol):
    def connectionMade(self):
        self.transport.write("Hello, world!")

    def dataReceived(self, data):
        print "Server said:", data
        self.transport.loseConnection()

class EchoFactory(protocol.ClientFactory):
    def buildProtocol(self, addr):
        return EchoClient()

    def clientConnectionFailed(self, connector, reason):
        print "Connection failed.", reason.getErrorMessage()
        reactor.stop()

    def clientConnectionLost(self, connector, reason):
        print "Connection lost."
        reactor.stop()

reactor.connectTCP("localhost", 8888, EchoFactory())
reactor.run()


reactor.connectTCP를 통해 tcp://localhost:8080 로 connect를 하는 것이고 
reactor에서는 해당 connection을 EchoFactory instance를 만들어 처리하도록 한다.

protocol을 처리하고자 buildProtocol()에서는 EchoClient를 생성하여 echo 동작을 수행하되 connection 오류 상황인 connect가 되지 않는 경우(server가 실행되지 않거나 해당 주소로 접근 불가 시)는 clientConnectionFailed()에서 처리하고
수립되었던 connection이 끊어지는 경우(server에서 connection을 close하거나 physical connection이 끊기 거나)에는 clientConnectionLost()에서 처리하도록 되어 있다.

client 이므로 connection이 성공하면
바로 server로 data를 보내고자  transport.wrtie()를 호출 하여 "hello world!" 전송하고
보내진 "hello world!"메세지는 server에서 다시 client로 보내질 테니
EchoClient.dataReceived()에서 다시 돌려받은 "hello world!" 메세지를  출력하고 끝남.

2014년 7월 8일 화요일

python 문법 중 특이점 대충 정리

python으로 된 코드를 봐야할 상황이 생겨
점프 투 파이썬(https://wikidocs.net/book/1)와
python documentation(https://docs.python.org/3.4/tutorial/index.html)을 보며
특이한 점만 대충 정리함.

문법이 스크립트언어 치곤 기존 c, c++과 유사하고 군더더기 없이 간결함.


[Coding Style]

http://legacy.python.org/dev/peps/pep-0008/

주요 style 권고들
  • Use 4-space indentation, and no tabs. (들여쓰기는 tab이 아닌 4개의 space)
  • Wrap lines so that they don’t exceed 79 characters. (한줄에 79 영문자 너비)
  • Use blank lines to separate functions and classes, and larger blocks of code inside functions. (한줄 띄우기로 function들, class들 구분)
  • When possible, put comments on a line of their own.
  • Use docstrings.
  • Use spaces around operators and after commas, but not directly inside bracketing constructs: a = f(1, 2) + g(3, 4). (콤마, 뒤에 한칸 띄워라)
  • Name your classes and functions consistently; the convention is to use CamelCase for classes and lower_case_with_underscores for functions and methods. Always use self as the name for the first method argument (see A First Look at Classes for more on classes and methods). (클래스 이름은 붙여서 쓰되 첫글자는 대문자, function/method는 소문자와 '_'의 조합, method들의 첫 argument는 'self'임)
  • Don’t use fancy encodings if your code is meant to be used in international environments. Python’s default, UTF-8, or even plain ASCII work best in any case. (UTF-8 encoding 기본 사용)
  • Likewise, don’t use non-ASCII characters in identifiers if there is only the slightest chance people speaking a different language will read or maintain the code.


[String]

. 짝만 맞으면 ', " 를 혼용해서 사용 가능

>>> 'spam eggs'  # single quotes
'spam eggs'
>>> 'doesn\'t'  # use \' to escape the single quote...
"doesn't"
>>> "doesn't"  # ...or use double quotes instead
"doesn't"
>>> '"Yes," he said.'
'"Yes," he said.'
>>> "\"Yes,\" he said."
'"Yes," he said.'
>>> '"Isn\'t," she said.'
'"Isn\'t," she said.'


[Flow Control]

'{', '}' 가 없고 ':'와 들여쓰기를 사용 함.

>>> x = int(input("Please enter an integer: "))
Please enter an integer: 42
>>> if x < 0:
...     x = 0
...     print('Negative changed to zero')
... elif x == 0:
...     print('Zero')
... elif x == 1:
...     print('Single')
... else:
...     print('More')
...

for each 지원

>>> # Measure some strings:
... words = ['cat', 'window', 'defenestrate']
>>> for w in words:
...     print(w, len(w))
...
cat 3
window 6
defenestrate 12

range(start, stop[, step]) 함수가 있어 for문에서 활용 가능

range(5, 10)
   5 through 9

range(0, 10, 3)
   0, 3, 6, 9

range(-10, -100, -30)
  -10, -40, -70

continue, break와는 다르게
아무것도 안하고 넘어가는 pass가 있음
C에서 ';'와 같은...

>>> class MyEmptyClass:
...     pass
...


[Function]

'def 함수이름(argument) : '로 시작

>>> def fib(n):    # write Fibonacci series up to n
...     """Print a Fibonacci series up to n."""
...     a, b = 0, 1
...     while a < n:
...         print(a, end=' ')
...         a, b = b, a+b
...     print()
...
>>> # Now call the function we just defined:
... fib(2000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597

default argument는 존재하고 사용법 비슷

Arbitrary Argument는 '*'를 argument 앞에 붙임. C는 '...'

>>> def concat(*args, sep="/"):
...    return sep.join(args)
...
>>> concat("earth", "mars", "venus")
'earth/mars/venus'
>>> concat("earth", "mars", "venus", sep=".")
'earth.mars.venus'

Lambda 존재

>>> def make_incrementor(n):
...     return lambda x: x + n
...
>>> f = make_incrementor(42)
>>> f(0)
42
>>> f(1)
43


[Module]

xxxx.py로 저장을 하고 module의 이름은 __name__ 변수에 저장됨.

> fibo.py

# Fibonacci numbers module

def fib(n):    # write Fibonacci series up to n
    a, b = 0, 1
    while b < n:
        print(b, end=' ')
        a, b = b, a+b
    print()

def fib2(n): # return Fibonacci series up to n
    result = []
    a, b = 0, 1
    while b < n:
        result.append(b)
        a, b = b, a+b
    return result

>>> import fibo

>>> fibo.fib(1000)
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
>>> fibo.fib2(100)
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>> fibo.__name__
'fibo'

script로 실행 시 "__main__" 값이 저장되므로
이를 이용해서 스크립트 실행 관련 처리를 할 수 있음.

python fibo.py <arguments>

if __name__ == "__main__":
    import sys
    fib(int(sys.argv[1]))

$ python fibo.py 50
1 1 2 3 5 8 13 21 34

import로는 실행 안됨.

>>> import fibo
>>>


[Scope]

scope를 확인할 수 있는 예제 scope_test()를 실행할 시점에는 global scope에 spam이 없음.
do_local()에서는 scope_test()내의 spam을 수정하는 것이 아니라 do_local()내의 spam을 수정하는 거고 do_nonlocal()에서는 nonlocal이 scope_test()의 spam에 binding을 시킴.
그리고 do_global()의 glocal keyword는 global scope의 spam에 binding 하게 되어 global scope에 spam 변수를 assign?

def scope_test():
    def do_local():
        spam = "local spam"
    def do_nonlocal():
        nonlocal spam
        spam = "nonlocal spam"
    def do_global():
        global spam
        spam = "global spam"
    spam = "test spam"
    do_local()
    print("After local assignment:", spam)
    do_nonlocal()
    print("After nonlocal assignment:", spam)
    do_global()
    print("After global assignment:", spam)

scope_test()
print("In global scope:", spam)


[class]

class ClassName:
    <statement-1>
    .
    .
    .
    <statement-N>

생성자 : __init__
소멸자 : __del__
모든 method의 첫번째 argument는 self

class Bag:
    def __init__(self):
        self.data = []
    def add(self, x):
        self.data.append(x)
    def addtwice(self, x):
        self.add(x)
        self.add(x)

상속 :
'class child(parent[, parent]*) :'

class DerivedClassName(BaseClassName):
    <statement-1>
    .
    .
    .
    <statement-N>

private variable 없음.
다만 '__'를 붙여서 private 처럼 생각하고 사용하는 방법은 있음.

class Mapping:
    def __init__(self, iterable):
        self.items_list = []
        self.__update(iterable)

    def update(self, iterable):
        for item in iterable:
            self.items_list.append(item)

    __update = update   # private copy of original update() method

class MappingSubclass(Mapping):

    def update(self, keys, values):
        # provides new signature for update()
        # but does not break __init__()
        for item in zip(keys, values):
            self.items_list.append(item)

연산자 오버로딩 :
def __add__(self, other) :



[Exception Handling]

try, except(as) 로 에러를 catch함.
raise로 exception 발생 시킬 수 있음.

import sys

try:
    f = open('myfile.txt')
    s = f.readline()
    i = int(s.strip())
except IOError as err:
    print("I/O error: {0}".format(err))
except ValueError:
    print("Could not convert data to an integer.")
except:
    print("Unexpected error:", sys.exc_info()[0])
    raise

clean-up 코드를 위한 finally 있음.

>>> try:
...     raise KeyboardInterrupt
... finally:
...     print('Goodbye, world!')
...
Goodbye, world!
KeyboardInterrupt