파이썬코딩

파이썬코드 SQL 표현식 언어

다음 레벨 업은 SQLlchemy의 SQL 표현 언어입니다. 다양한 작업을 위한 SQL 생성 기능을 소개합니다. 표현식 언어는 하위 엔진 계층보다 더 많은 SQL 방언 차이를 처리합니다. 관계형 데이터베이스 애플리케이션에 편리한 중간 접근 방식이 될 수 있습니다.

다음은 동물원 테이블을 만들고 채우는 방법입니다. 다시 말하지만, 이것들은 단일 프로그램의 연속된 조각들입니다.

가져오기 및 연결은 이전과 동일합니다.

 

>>> import sqlalchemy as sa
>>> conn = sa.create_engine('sqlite://') 

동물원 테이블을 정의하기 위해 SQL 대신 표현식 언어 중 일부를 사용하기 시작합니다.

 

  >>> meta = sa.MetaData()

    >>> zoo = sa.Table('zoo', meta,

  •     ...      sa.Column('critter', sa.String, primary_key=True),
  •  
  •     ...      sa.Column('count', sa.Integer),
  •  
  •     ...      sa.Column('damages', sa.Float)
  •     ...    )
  •     >>> meta.create_all(conn)
  •  

앞의 예에서 여러 줄 통화의 괄호를 확인하십시오. 표() 메서드의 구조는 표 구조와 일치합니다. 표에 세 개의 열이 있는 것처럼 표() 메서드 호출의 괄호 안에 열()에 대한 세 개의 호출이 있습니다.

한편, zoo는 SQL 데이터베이스 세계와 파이썬 데이터 구조 세계를 연결하는 마법의 객체입니다.

표현 언어 함수가 더 많은 데이터를 삽입합니다.

 

 ... conn.execute(zoo.insert(('bear', 2, 1000.0)))

    <sqlalchemy.engine.result.ResultProxy object at 0x1017ea910>

    >>> conn.execute(zoo.insert(('weasel', 1, 2000.0)))

    <sqlalchemy.engine.result.ResultProxy object at 0x1017eab10>

    >>> conn.execute(zoo.insert(('duck', 10, 0)))

    <sqlalchemy.engine.result.ResultProxy object at 0x1017eac50>

 

그런 다음 SELECT 문을 만듭니다(zoo.select()). 예를 들어, SELECT * FROM ZOO가 일반 SQL에서 수행하는 것과 같이 동물원 개체가 나타내는 테이블에서 모든 것을 선택합니다.

 

>>> result = conn.execute(zoo.select()) 

마지막으로 다음과 같은 결과를 얻습니다.

>>> rows = result.fetchall()
>>> print(rows)
[('bear', 2, 1000.0), ('weasel', 1, 2000.0), ('duck', 10, 0.0)] 

객체-상대 매퍼

마지막 섹션에서 zoo 객체는 SQL과 파이썬 간의 중간 수준 연결이었다. SQLlchemy의 최상위 계층에서 ORM(Object-Relational Mapper)은 SQL 표현 언어를 사용하지만 실제 데이터베이스 메커니즘을 보이지 않게 하려고 합니다. 클래스를 정의하면 ORM이 데이터베이스로 데이터를 가져오거나 내보내는 방법을 처리합니다. "객체-관계형 맵퍼"라는 복잡한 구절 뒤에 숨겨진 기본 개념은 여러분이 코드에 있는 객체를 참조할 수 있고, 따라서 관계형 데이터베이스를 사용하면서 파이썬이 동작하는 방식에 근접할 수 있다는 것입니다.

 

동물원 클래스를 정의해서 ORM에 연결하겠습니다. 이번에는 SQLite에서 zoo.db 파일을 사용하도록 하여 ORM이 작동했는지 확인합니다.

 

앞의 두 절에서와 같이, 다음에 나오는 토막글은 실제로 설명으로 구분된 하나의 프로그램입니다. 이해가 안 가더라도 걱정하지 마세요. SQLArchemy 문서에는 모든 세부 사항이 포함되어 있습니다. 이 내용은 복잡해질 수 있습니다. 이 장에서 논의한 접근 방식 중 자신에게 적합한 방법을 결정할 수 있도록 이 작업을 수행하는 데 얼마나 많은 작업이 필요한지 파악해 주시기 바랍니다.

초기 가져오기는 동일하지만 이번에는 다른 것도 필요합니다.

 

>>> import sqlalchemy as sa
>>> from sqlalchemy.ext.declarative import declarative_base 

여기, 우리는 다음과 같은 연결을 만듭니다.

 

 >>> conn = sa.create_engine('sqlite:///zoo.db')

 

이제 SQLArchemy의 ORM에 대해 알아보겠습니다. Zoo 클래스를 정의하고 해당 속성을 테이블 열과 연결합니다.

 

>>> Base = declarative_base() >>> class Zoo(Base): 

  •     ...      __tablename__ = 'zoo'
  •  
  •     ...      critter = sa.Column('critter', sa.String, primary_key=True)
  •  
  •     ...      count = sa.Column('count', sa.Integer)
  •  
  •     ...      damages = sa.Column('damages', sa.Float)
  •  
  • ...  def __init__(self, critter, count, damages):
  •     ...          self.critter = critter
  •  
  •     ...          self.count = count
  •  
  •     ...          self.damages = damages
  •  
  • ...  def __repr__(self):
  • ...  return "<Zoo({}, {}, {})>".format(self.critter, self.count, self.damages) 
  •  
  • 다음 행은 데이터베이스와 테이블을 마법처럼 작성합니다.
  • >>> Base.metadata.create_all(conn)

  • 그런 다음 파이썬 개체를 만들어 데이터를 삽입할 수 있습니다. ORM은 이러한 것들을 관리한다.
  • 내부:
  •  
  • >>> first = Zoo('duck', 10, 0.0)
  •     >>> second = Zoo('bear', 2, 1000.0)
  •     >>> third = Zoo('weasel', 1, 2000.0)
  •     >>> first
  •     <Zoo(duck, 10, 0.0)>
  •  
  • 다음으로, 우리는 ORM이 우리를 SQL 랜드로 데려가게 합니다. 데이터베이스와 대화하기 위한 세션을 만듭니다.
  •  
  • . >>> from sqlalchemy.orm import sessionmaker >>> Session = sessionmaker(bind=conn)
    >>> session = Session()
  • 세션 내에서, 우리는 우리가 만든 세 개의 객체를 데이터베이스에 작성합니다. add() 함수는 하나의 객체를 추가하고 add_all()은 목록을 추가합니다.
  • .
  •   >>> session.add(first)
  •     >>> session.add_all([second, third])
  •  

  • 마지막으로, 우리는 모든 것을 완료하도록 강요해야 합니다.
  • >>> session.commit()

효과가 있던가요? 현재 디렉터리에 zoo.db 파일을 만들었습니다. 사용할 수 있습니다.

확인할 명령줄 sqlite3 프로그램:

 

  • $ sqlite3 zoo.db
    SQLite version 3.6.12
    Enter ".help" for instructions
    Enter SQL statements terminated with a ";" sqlite> .tables
    zoo
    sqlite> select * from zoo; 
  • duck|10|0.0

bear|2|1000.0

 

 weasel|1|2000.0

 

이 섹션의 목적은 ORM이 무엇이고 높은 수준에서 어떻게 작동하는지 보여주기 위한 것이다. SQLlchemy의 작성자가 전체 자습서를 작성했습니다. 이 내용을 읽은 후 다음 중 필요에 가장 적합한 수준을 결정하십시오.

 

• 이전 SQLite 섹션에서와 같이 일반 DB-API

 

• SQLArchemy 엔진룸

 

• SQLArchemy 표현 언어

 

• SQLChemy ORM

 

SQL의 복잡성을 피하기 위해 ORM을 사용하는 것은 자연스러운 선택인 것 같습니다. 하나 쓸까요? 어떤 사람들은 ORM을 피해야 한다고 생각하지만, 다른 사람들은 이 비판이 지나치다고 생각한다. 누가 옳든, ORM은 추상화입니다. 그리고 모든 추상화들은 어느 순간 무너집니다. 그것들은 새어나갑니다. ORM이 원하는 작업을 수행하지 않는 경우 SQL에서 ORM의 작동 방식과 해결 방법을 모두 파악해야 합니다. 인터넷 밈을 빌리려면: 어떤 사람들은 어떤 문제에 직면했을 때, "알아요, ORM을 써야겠어요."라고 생각합니다. 이제 그들은 두 가지 문제를 안고 있습니다. ORM은 거의 사용하지 않으며 대부분 간단한 애플리케이션에 사용합니다. 응용 프로그램이 그렇게 간단한 경우 스트레이트 SQL(또는 SQL 표현식 언어)을 사용할 수도 있습니다.

 

또는 데이터 집합과 같은 간단한 것을 시도할 수 있습니다. SQL, JSON 및 CSV 스토리지를 위한 간단한 ORM을 제공하는 SQLLchemy는 SQL, JSON 및 CSV 스토리지를 제공합니다.

 

파이썬코드 Db-api sqlite mysql

DB-API 

 

API(응용 프로그램 프로그래밍 인터페이스)는 일부 서비스에 액세스하기 위해 호출할 수 있는 함수 집합입니다. DB-API는 관계형 데이터베이스에 액세스하기 위한 Python의 표준 API입니다. 이를 사용하여 각 데이터베이스에 대해 별도의 프로그램을 작성하는 대신 여러 종류의 관계형 데이터베이스에서 작동하는 단일 프로그램을 작성할 수 있습니다. 그것은 자바의 JDBC나 펄의 dbi와 비슷하다.

주요 기능은 다음과 같습니다.

연결하다

데이터베이스에 연결합니다. 사용자 이름, 암호, 서버 주소 등의 인수를 포함할 수 있습니다.

 

커서가 있는

쿼리를 관리할 커서 개체를 만듭니다. 사형 집행 집행 집행 집행 집행 집행 집행 집행 집행 집행 집행 집행 집행 집행 집행 집행 집행 집행.

데이터베이스에 대해 하나 이상의 SQL 명령을 실행합니다.

fetchone() , fetchmany() 및 fetchall() 실행에서 결과를 가져옵니다.

다음 절의 Python 데이터베이스 모듈은 DB-API를 준수하며, 종종 확장과 세부 사항의 일부 차이점이 있습니다.

 

SQLite

SQLite는 우수하고 가벼운 오픈 소스 관계형 데이터베이스입니다. 표준 파이썬 라이브러리로 구현되며 데이터베이스를 일반 파일에 저장합니다. 이 파일들은 ma ch chines 및 운영 체제 간에 이동 가능하므로 SQLite는 단순한 관계형 데이터베이스 애플리케이션을 위한 매우 휴대성이 뛰어난 솔루션이 됩니다. MySQL 또는 Postgre만큼 완벽한 기능은 아닙니다.SQL은 지원하지만 여러 명의 동시 사용자를 관리합니다. 웹 브라우저, 스마트폰 및 기타 응용 프로그램은 SQLite를 내장 데이터베이스로 사용합니다.

사용 또는 작성할 로컬 SQLite 데이터베이스 파일에 대한 연결()로 시작합니다. 이 파일은 부모가 다른 서버에 있는 테이블로 사용하는 디렉토리와 같은 데이터베이스와 동일합니다. 특수 문자열 ':memory:'는 메모리에만 데이터베이스를 만듭니다. 이 문자열은 빠르고 테스트에 유용하지만 프로그램이 종료되거나 컴퓨터가 다운되면 데이터가 손실됩니다.

 

다음 예로, 번창하는 길가 애완 동물원의 사업을 관리하기 위해 Enterprise.db라는 데이터베이스와 테이블 동물원(table zoo)을 만들어 보겠습니다. 테이블 열은 다음과 같습니다.

생물의 가변 길이 문자열 및 기본 키

수를 세다

이 동물에 대한 현재 재고의 정수 개수

손해

현재 동물과 인간의 상호작용으로 인한 손실의 액수입니다.

 

>>> import sqlite3
>>> conn = sqlite3.connect('enterprise.db') >>> curs = conn.cursor()
>>> curs.execute('''CREATE TABLE zoo 

        (critter VARCHAR(20) PRIMARY KEY,

         count INT,

         damages FLOAT)''')

<sqlite3.Cursor object at 0x1006a22d0>

Python의 삼중따옴표는 SQL 쿼리와 같은 긴 문자열을 만들 때 유용합니다.

 

이제 동물원에 동물을 추가하세요.

 

 >>> curs.execute('INSERT INTO zoo VALUES("duck", 5, 0.0)')

    <sqlite3.Cursor object at 0x1006a22d0>

    >>> curs.execute('INSERT INTO zoo VALUES("bear", 2, 1000.0)')

    <sqlite3.Cursor object at 0x1006a22d0>

 

자리 표시자를 사용하여 데이터를 더 안전하게 삽입할 수 있습니다.

 

  >>> ins = 'INSERT INTO zoo (critter, count, damages) VALUES(?, ?, ?)'

    >>> curs.execute(ins, ('weasel', 1, 2000.0))

    <sqlite3.Cursor object at 0x1006a22d0>

 

이번에는 SQL에 물음표 3개를 사용하여 3개의 값을 삽입한 다음 이 3개의 값을 목록으로 실행() 함수에 전달할 계획임을 나타냅니다. 보험 계약자는 인용과 같은 지루한 세부 사항을 처리합니다. SQL 주입으로부터 사용자를 보호합니다. SQL 주입은 웹에서 일반적으로 시스템에 악의적인 SQL 명령을 삽입하는 외부 공격입니다.

이제, 우리가 우리의 모든 동물들을 다시 꺼낼 수 있는지 봅시다.

 

>>> curs.execute('SELECT * FROM zoo') <sqlite3.Cursor object at 0x1006a22d0> >>> rows = curs.fetchall()
>>> print(rows) 

[('duck', 5, 0.0), ('bear', 2, 1000.0), ('weasel', 1, 2000.0)] 

다시 불러오죠. 하지만 숫자대로 정렬합니다.

 

  >>> curs.execute('SELECT * from zoo ORDER BY count')

    <sqlite3.Cursor object at 0x1006a22d0>

    >>> curs.fetchall()

    [('weasel', 1, 2000.0), ('bear', 2, 1000.0), ('duck', 5, 0.0)]

 

이봐, 우린 내림차순으로 원했어.

   >>> curs.execute('SELECT * from zoo ORDER BY count DESC')

    <sqlite3.Cursor object at 0x1006a22d0>

    >>> curs.fetchall()

    [('duck', 5, 0.0), ('bear', 2, 1000.0), ('weasel', 1, 2000.0)]

 

어떤 종류의 동물이 가장 비용이 많이 드나요?

 

 >>> curs.execute('''SELECT * FROM zoo WHERE

    ...     damages = (SELECT MAX(damages) FROM zoo)''')

    <sqlite3.Cursor object at 0x1006a22d0>

    >>> curs.fetchall()

    [('weasel', 1, 2000.0)]

 

여러분은 곰들이라고 생각했을 것입니다. 항상 실제 데이터를 확인하는 것이 가장 좋습니다.

SQLite를 떠나기 전에 정리를 해야 합니다. 연결과 커서를 연 경우 작업이 완료되면 커서를 닫아야 합니다.

 

    >>> curs.close()

    >>> conn.close()

 

MySQL

MySQL은 매우 널리 사용되는 오픈 소스 관계형 데이터베이스입니다. SQLite와 달리 실제 서버이므로 클라이언트가 네트워크상의 다른 장치에서 액세스할 수 있습니다.

MysqlDB는 가장 인기 있는 MySQL 드라이버였지만 아직 파이썬 3으로 포팅되지는 않았다. 표 8-3에는 파이썬에서 MySQL에 액세스하는 데 사용할 수 있는 드라이버가 나와 있습니다.

표 8-3. MySQL 드라이버

 

MySQL Connector PYMySQL
oursql 

Link 

http://bit.ly/mysql-cpdg 

https://github.com/petehunt/ PyMySQL/ 

http://pythonhosted.org/oursql/ 

Pypi package Import as 

mysql-connector- mysql.connector python 

Notes 

Requires the MySQL C client libraries. 

 

PostgreSQl

링크

http://bit.ly/mysql-cpdg

https://github.com/petehunt/ PyMySQL/

http://pythonhosted.org/oursql/

Pypi 패키지 가져오기 위치

mysql-sql.mysql.mysql

메모들

MySQL C 클라이언트 라이브러리가 필요합니다.

Pymysql usql

pymysql

usql

포스트그레SQL은 MySQL보다 여러 면에서 더 많은 이점을 제공하는 완전한 기능의 오픈 소스 관계형 데이터베이스입니다. 표 8-4는 Python 드라이버에 액세스하는 데 사용할 수 있는 드라이버를 보여줍니다.

포스트그레SQL 드라이버

 

가장 인기 있는 드라이버는 psycopg2이지만 Postgre를 설치해야 한다.SQL 클라이언트 라이브러리.

 

SQLArchemy

SQL은 모든 관계형 데이터베이스에 대해 완전히 동일하지는 않으며 DB-API는 지금까지만 지원합니다. 각 데이터베이스는 그 특징과 철학을 반영하는 특정한 방언을 구현한다. 많은 도서관들이 이런 차이점들을 어떻게든 메우려고 노력한다. 가장 널리 사용되는 데이터베이스 간 파이썬 라이브러리는 SQLArchemy입니다.

그것은 표준 도서관에는 없지만, 많은 사람들에 의해 잘 알려져 있고 사용되고 있습니다. 다음 명령을 사용하여 시스템에 설치할 수 있습니다.

 

$ pip install sqlalchemy

• 가장 낮은 수준은 데이터베이스 연결 풀, SQL 명령 실행 및 결과 반환을 처리합니다. DB-API에 가장 가깝습니다.

 

• 다음은 SQL 표현 언어인 Pythonic SQL Builder입니다.

 

• 가장 높은 계층은 SQL 식을 사용하는 ORM(Object Relational Model) 계층입니다.

 

언어 및 관계형 데이터 구조와 응용 프로그램 코드를 바인딩합니다.

계속 진행하면서 이러한 수준의 용어가 무엇을 의미하는지 이해하게 될 것입니다. SQLArchemy는 이전 절에 설명된 데이터베이스 드라이버와 함께 작동합니다. 드라이버를 가져올 필요가 없습니다. SQLLCemy에 제공한 초기 연결 문자열이 드라이버를 결정합니다. 이 문자열은 다음과 같습니다.

 

  • dialect + driver :// user : password @ host : port / dbname

이 문자열에 입력한 값은 다음과 같습니다.

사투리를 쓰다

데이터베이스 유형

운전사의

해당 데이터베이스에 사용할 특정 드라이버

사용자 및 암호

데이터베이스 인증 문자열

숙주와 항구

데이터베이스 서버의 위치(: 이 서버의 표준 포트가 아닌 경우에만 필요)

dbname

서버에서 처음 연결할 데이터베이스

 

  • Table 8-5 lists the dialects and drivers.
    Table 8-5. SQLAlchemy connection

dialect 

sqlite

mysql

mysql

mysql

postgresql

postgresql

driver 

pysqlite (or omit) mysqlconnector pymysql
oursql psycopg2 pypostgresql 

엔진 층

먼저, 기본 DB- API 기능보다 조금 더 낮은 수준의 SQLlchemy를 사용해 보겠습니다.

파이썬에 이미 내장된 SQLite를 사용해 보겠습니다. SQLite에 대한 연결 문자열이 호스트, 포트, 사용자 및 암호를 건너뜁니다. dbname은 데이터베이스를 저장하는 데 사용할 파일을 SQLite에 알려줍니다. dbname을 생략하면 SQLite는 메모리에 데이터베이스를 작성합니다. dbname이 슬래시(/)로 시작하는 경우 컴퓨터의 절대 파일 이름입니다(예: Windows의 C:\\). 그렇지 않으면 현재 디렉토리와 관련이 있습니다.

다음 세그먼트는 설명을 위해 여기에서 분리된 한 프로그램의 모든 부분입니다.

먼저 필요한 것을 가져오셔야 합니다. 다음은 문자열 sa를 사용하여 SQLLCemy 메서드를 참조할 수 있는 가져오기 별칭의 예입니다. 주로 sa가 sqlalchemy보다 훨씬 쉽게 입력되기 때문에 이 작업을 수행합니다.

 

>>> import sqlalchemy as sa

데이터베이스에 연결하고 메모리에 데이터베이스에 대한 저장소 만들기(인수 문자열)

'sqlite://:memory:'도 작동합니다.

 

>>> conn = sa.create_engine('sqlite://') 

다음과 같은 세 개의 열로 구성된 zoo라는 데이터베이스 테이블을 만듭니다.

 

>>> conn.execute('''CREATE TABLE zoo 

...

...

...

<sqlalchemy.engine.result.ResultProxy object at 0x1017efb10>

 

conn.execute()를 실행하면 ResultProxy라는 SQLLCemy 개체를 반환합니다. 너는 곧 그것을 어떻게 해야 할지 알게 될 것이다.

그나저나, 데이터베이스 표를 만들어 본 적이 없다면 축하드립니다. 버킷 리스트에서 하나를 체크하세요.

이제 비어 있는 새 테이블에 세 가지 데이터 세트를 삽입합니다.

 

    >>> ins = 'INSERT INTO zoo (critter, count, damages) VALUES (?, ?, ?)'

    >>> conn.execute(ins, 'duck', 10, 0.0)

    <sqlalchemy.engine.result.ResultProxy object at 0x1017efb50>

    >>> conn.execute(ins, 'bear', 2, 1000.0)

    <sqlalchemy.engine.result.ResultProxy object at 0x1017ef090>

    >>> conn.execute(ins, 'weasel', 1, 2000.0)

    <sqlalchemy.engine.result.ResultProxy object at 0x1017ef450>

 

그런 다음 데이터베이스에 방금 입력한 모든 내용을 요청하십시오.

    >>> rows = conn.execute('SELECT * FROM zoo')

 

SQLArchemy에서 행은 목록이 아니라 직접 인쇄할 수 없는 특별한 ResultProxy입니다.

 

>>> print(rows)
<sqlalchemy.engine.result.ResultProxy object at 0x1017ef9d0> 

그러나 목록처럼 반복할 수 있으므로 한 번에 다음 행을 얻을 수 있습니다.

 

>>> for row in rows: ... print(row) ...
('duck', 10, 0.0) ('bear', 2, 1000.0) ('weasel', 1, 2000.0) 

앞에서 보신 SQLite DB-API 예제와 거의 동일합니다. 한 가지 장점은 맨 위에 있는 데이터베이스 드라이버를 가져올 필요가 없다는 것입니다. SQLArchemy는 연결 문자열에서 이를 알아냈습니다. 연결 문자열을 변경하면 이 코드가 다른 유형의 데이터베이스로 이동될 수 있습니다. 또 다른 장점은 SQLlchemy의 연결 풀링이며, 이 풀링은 설명서 사이트에서 확인할 수 있습니다.

 

 

파이썬코드 피클을 사용하여 직렬화

데이터 구조를 파일에 저장하는 것을 직렬화라고 합니다. JSON과 같은 형식을 사용하려면 파이썬 프로그램의 모든 데이터 유형을 직렬화하기 위해 일부 사용자 지정 변환기가 필요할 수 있습니다. 파이썬은 특별한 바이너리 형식으로 객체를 저장하고 복원할 수 있는 피클 모듈을 제공한다.

날짜/시간 객체를 만났을 때 JSON이 어떻게 정신을 잃었는지 기억하십니까? 피클에 대한 확률 없음:

 

>>> import pickle
>>> import datetime
>>> now1 = datetime.datetime.utcnow()
>>> pickled = pickle.dumps(now1)
>>> now2 = pickle.loads(pickled)
>>> now1
datetime.datetime(2014, 6, 22, 23, 24, 19, 195722) >>> now2
datetime.datetime(2014, 6, 22, 23, 24, 19, 195722) 

피클은 당신의 클래스나 오브젝트에서도 작동한다. 문자열로 처리될 때 문자열 'tiny'를 반환하는 Tiny라는 작은 클래스를 정의합니다.

 

>>> import pickle
>>> class Tiny():
... def __str__(self): ... return 'tiny' ...
>>> obj1 = Tiny() 

>>> obj1
<__main__.Tiny object at 0x10076ed10>
>>> str(obj1)
'tiny'
>>> pickled = pickle.dumps(obj1)
>>> pickled b'\x80\x03c__main__\nTiny\nq\x00)\x81q\x01.' >>> obj2 = pickle.loads(pickled)
>>> obj2
<__main__.Tiny object at 0x10076e550>
>>> str(obj2)
'tiny' 

절인 것은 물체 obj1로부터 만들어진 절인 2진법 끈이다. 우리는 그것을 객체 obj2로 다시 변환하여 obj1의 복사본을 만들었습니다. 덤프()를 사용하여 파일에 피클하고 로드()를 사용하여 파일에서 피클을 해제합니다.

 

피클은 파이썬 개체를 만들 수 있기 때문에 이전 섹션에서 설명한 것과 동일한 보안 경고 잉그가 적용됩니다. 신뢰하지 않는 것을 풀지 마라.

 

구조화된 이진 파일

일부 파일 형식은 특정 데이터 구조를 저장하기 위해 설계되었지만, 규격 데이터베이스도 NoSQL 데이터베이스도 아니다. 다음 절에서는 그 중 일부를 제시합니다.

 

스프레드시트

스프레드시트, 특히 Microsoft Excel은 널리 사용되는 이진 데이터 형식입니다. 스프레드시트를 CSV 파일에 저장할 수 있는 경우 앞서 설명한 표준 CSV 모듈을 사용하여 스프레드시트를 읽을 수 있습니다. 이진 xls 파일이 있는 경우 xlrd는 읽고 쓰기를 위한 타사 패키지입니다.

 

HDF5

HDF5는 다차원 또는 계층적 숫자 데이터를 위한 이진 데이터 형식입니다. 대용량 데이터셋(기가바이트 ~ 테라바이트)에 대한 빠른 랜덤 액세스가 일반적인 요구 사항인 과학 분야에서 주로 사용됩니다. 어떤 경우에는 HDF5가 데이터베이스의 좋은 대안이 될 수 있지만, 어떤 이유로 HDF5는 비즈니스 세계에서 거의 알려져 있지 않습니다. 충돌하는 쓰기로부터 데이터베이스를 보호할 필요가 없는 WORM(Write Once/Read Many) 애플리케이션에 가장 적합합니다. 다음은 유용한 몇 가지 모듈입니다.

 

h5py는 완전 저수준 인터페이스입니다. 설명서 및 코드를 읽습니다.

 

PyTables는 데이터베이스와 유사한 기능을 가진 좀 더 높은 레벨입니다. 설명서와 코드를 읽습니다.

이 두 가지 모두 부록 C에서 파이썬의 과학적 적용 측면에서 논의된다. 여기서 말하는 것은 대량의 데이터를 저장 및 검색해야 하는 경우 일반적인 데이터베이스 솔루션뿐만 아니라 외부 솔루션을 고려할 의사가 있는 경우입니다. 좋은 예는 HDF5 형식의 다운로드 가능한 노래 데이터가 있는 Million Song 데이터 세트입니다

 

관계형 데이터베이스

관계형 데이터베이스는 약 40년 밖에 되지 않았지만 컴퓨팅 세계 어디에서나 볼 수 있습니다. 여러분은 거의 틀림없이 한 번 혹은 여러 번 그들을 상대해야 할 것입니다. 그러면 다음과 같은 혜택을 누릴 수 있습니다.

 

• 여러 동시 사용자의 데이터 액세스

• 해당 사용자에 의한 손상 방지

• 효율적인 데이터 저장 및 검색 방법

• 스키마에 의해 정의되고 제약에 의해 제한되는 데이터

• 다양한 유형의 데이터에 걸친 관계를 찾기 위한 결합

• 선언적(필수적) 질의 언어: SQL(구조화된 쿼리 언어)

 

이것들은 서로 다른 종류의 데이터들 사이의 관계를 표의 형태로 보여주기 때문에 관계형이라고 불린다. 예를 들어, 앞의 메뉴 예에서는 각 품목과 가격 사이에 관계가 있습니다.

 

테이블은 스프레드시트와 유사한 행과 열의 그리드입니다. 테이블을 만들려면 테이블 이름을 지정하고 열의 순서, 이름 및 유형을 지정하십시오. 결측 데이터(null이라고 함)를 허용하도록 열을 정의할 수 있지만 각 행에는 동일한 열이 있습니다. 메뉴 예제에서는 판매되는 각 품목에 대해 하나의 행으로 테이블을 만들 수 있습니다. 각 품목에는 가격에 대한 열을 포함하여 동일한 열이 있습니다.

 

열 또는 열 그룹은 일반적으로 테이블의 기본 키이며 해당 값은 테이블에서 고유해야 합니다. 이렇게 하면 테이블에 동일한 데이터를 두 번 이상 추가할 수 없습니다. 이 키는 쿼리 중 빠른 검색을 위해 인덱싱됩니다. 색인은 책 색인처럼 작동하기 때문에 특정 행을 빨리 찾을 수 있습니다.

각 테이블은 디렉토리 내의 파일처럼 상위 데이터베이스 내에 있습니다. 두 단계의 위계질서가 상황을 조금 더 잘 정리하도록 도와줍니다.

 

예, 데이터베이스라는 단어는 서버, 테이블 컨테이너 및 여기에 저장된 데이터로 여러 가지 방법으로 사용됩니다. 모든 항목을 동시에 참조하는 경우 데이터베이스 서버, 데이터베이스 및 데이터라고 부르는 것이 도움이 될 수 있습니다.

 

키가 아닌 일부 열 값으로 행을 찾으려면 해당 열에 보조 인덱스를 정의합니다. 그렇지 않은 경우, 데이터베이스 서버는 테이블 검색을 수행해야 합니다. 즉, 일치하는 열 값을 찾기 위해 모든 행을 무차별적으로 검색합니다.

테이블은 외부 키를 사용하여 서로 연관될 수 있으며 열 값은 이러한 키에 변형될 수 있습니다.

 

SQL

SQL은 API나 프로토콜이 아니라 선언적 언어입니다. 어떻게 하느냐 보다는 원하는 것을 말합니다. 이것은 관계형 데이터베이스의 보편적인 언어입니다. SQL 쿼리는 클라이언트가 데이터베이스 서버로 보내는 텍스트 문자열로, 이 문자열로 수행할 작업을 결정합니다.

다양한 SQL 표준 정의가 존재했지만, 모든 데이터베이스 공급업체는 자체적인 수정과 확장을 추가하여 많은 SQL 방언들을 만들어냈다. 데이터를 관계형 데이터베이스에 저장하면 SQL이 어느 정도 휴대성을 제공합니다. 그러나 방언 및 운영상의 차이로 인해 데이터를 다른 유형의 데이터베이스로 이동하기가 어려울 수 있습니다.

SQL 문에는 두 가지 주요 범주가 있습니다.

DDL(데이터 정의 언어)

테이블, 데이터베이스 및 사용에 대한 작성, 삭제, 제약 조건 및 사용 권한 처리

DML(데이터 조작 언어)

데이터 삽입, 선택, 업데이트 및 삭제 처리 표 8-1은 기본 SQL DDL 명령을 나열합니다.

표 8-1. 기본 SQL DDL 명령

 

Operation 

Create a database
Select current database
Delete a database and its tables Create a table
Delete a table
Remove all rows from a table 

SQL pattern 

CREATE DATABASE dbname
USE dbname
DROP DATABASE dbname CREATE TABLE tbname ( coldefs ) DROP TABLE tbname 

TRUNCATE TABLE tbname 

SQL example 

CREATE DATABASE d
USE d
DROP DATABASE d
CREATE TABLE t (id INT, count INT) DROP TABLE t 

TRUNCATE TABLE t 

 

왜 대문자는 다 쓰죠? SQL은 대소문자를 구분하지 않지만 코드 검사에서 키워드를 SHOUT하는 것이 전통입니다. 열 이름과 구별하기 위해 사용합니다.

관계형 데이터베이스의 주요 DML 작업은 흔히 CRUD 약어로 알려져 있습니다.

• SQL INSERT 문을 사용하여 작성

• SELECT를 사용하여 읽기

• UPDATE를 사용하여 업데이트

• DELETE를 사용하여 삭제

표 8-2는 SQL DML에 사용할 수 있는 명령을 살펴본다. 표 8-2. 기본 SQL DML 명령

 

Operation 

Add a row 

Select all rows and columns Select all rows, some columns 

Select some rows, some columns 

Change some rows in a column Delete some rows 

 

SQL pattern 

INSERT INTO tbname VALUES( ...) 

SELECT * FROM tbname SELECT cols FROM tbname 

SELECT cols FROM tbname WHERE condition 

UPDATE tbname SET col = value WHERE condition 

DELETE FROM tbname WHERE condition 

SQL example 

INSERT INTO t VALUES(7, 40) 

SELECT * FROM t
SELECT id, count FROM t 

SELECT id, count from t WHERE count > 5 AND id = 9 

UPDATE t SET count=3 WHERE id=5 

DELETE FROM t WHERE count <= 10 OR id = 16 

 

 

 

 

 

 

 

 

 

 

파이썬코드 Mangle Data Like a Pro

이번 포스팅에서는 데이터 길들이기 위한 여러 가지 기술에 대해 알아봅니다. 이들 대부분은 다음과 같은 내장 파이썬 데이터 유형에 관한 것이다.

줄들

텍스트 데이터에 사용되는 유니코드 문자 시퀀스.

바이트와 바이패스

이진 데이터에 사용되는 8비트 정수 시퀀스입니다.

텍스트 문자열

텍스트는 대부분의 독자들에게 가장 익숙한 데이터 유형입니다. 따라서 파이썬에서 텍스트 문자열의 강력한 기능 중 몇 가지를 살펴보겠습니다.

유니코드

지금까지 이 책의 모든 텍스트 예제는 평범한 옛 아스키이다. ASCII는 1960년대에 정의되었는데, 그 당시 컴퓨터는 냉장고 크기였고 계산을 조금 더 잘했다. 컴퓨터 저장의 기본 단위는 바이트이며, 바이트는 8비트에 256개의 고유값을 저장할 수 있다. 여러 가지 이유로 ASCII는 대문자 26개, 소문자 26개, 숫자 10개, 일부 펑크음 기호, 일부 띄어쓰기 문자 및 일부 비인쇄 제어 코드 등 7비트(128개의 고유 값)만 사용했습니다.

불행하게도, 세계는 ASCII가 제공하는 것보다 더 많은 글자를 가지고 있다. 당신은 식당에서 핫도그를 먹을 수 있지만, 카페에서는 절대로 게뷔르츠트라미네르1을 먹지 않는다. 더 많은 문자와 기호를 추가하기 위한 많은 시도가 있었고, 여러분은 때때로 그것들을 볼 수 있을 것입니다. 그 중 몇 가지 예를 들 수 있습니다.

 

1. 이 와인은 독일에 음라우트가 있는데 프랑스에서는 잃어버려요.

Latin-1, or ISO 8859-1
• Windows code page 1252 

이들 각각은 8비트를 모두 사용합니다. 하지만 그것조차도 충분하지 않습니다. 특히 비유럽 언어가 필요할 때는요. 유니코드는 수학과 다른 분야의 기호와 더불어 세계 모든 언어의 문자를 정의하는 지속적인 국제 표준이다.

유니코드는 플랫폼, 프로그램, 언어와 상관없이 모든 문자에 대해 고유한 번호를 제공합니다.

 

유니코드 코드 차트 페이지에는 이미지가 있는 현재 정의된 모든 문자 집합에 대한 링크가 있습니다. 최신 버전(6.2)에서는 각각 고유한 이름과 식별 번호를 가진 110,000자 이상의 문자를 정의합니다. 문자는 평면이라고 하는 8비트 집합으로 나뉩니다. 처음 256면은 기본 다국어 평면이다. 자세한 내용은 유니코드 평면에 대한 위키피디아 페이지를 참조하십시오.

 

파이썬 3 유니코드 문자열

Python 3 문자열은 바이트 배열이 아닌 유니코드 문자열입니다. 이는 일반 바이트 문자열과 유니코드 문자 문자열을 구분하는 파이썬 2와 비교할 때 가장 큰 변화입니다.

 

유니코드 ID 또는 문자 이름을 알고 있는 경우 파이썬 문자열에서 사용할 수 있습니다. 다음은 몇 가지 예입니다.

 

• \u 다음에 4개의 16진수2는 유니코드의 256개의 기본 다국어 평면 중 하나에 있는 문자를 지정합니다. 처음 두 개는 평면 번호(00에서 FF)이고 다음 두 개는 평면 내 문자 색인입니다. 평면 00은 오래된 ASCII이며, 평면 내의 문자 위치는 ASCII와 동일합니다.

 

• 고차원 문자의 경우 비트가 더 필요합니다. Python 이스케이프 시퀀스는 \U 다음에 8개의 16진수 문자가 나옵니다. 가장 왼쪽 문자는 0이어야 합니다.

 

• 모든 문자에 대해 \N{ 이름 }을(를) 사용하여 표준 이름으로 지정할 수 있습니다. 유니코드 문자 이름 색인 페이지에는 이러한 항목이 나열됩니다.

파이썬 유니코드다 모듈에는 양방향으로 변환하는 기능이 있습니다.

 

• 검색—대소문자를 구분하지 않는 이름을 사용하고 유니코드 문자를 반환합니다.

 

• 이름 표시—유니코드 문자를 사용하고 대문자 이름을 반환합니다.

 

다음 예에서는 Python Unicode char act acter를 사용하여 이름을 조회한 다음 이름(원래 문자와 일치해야 함)에서 문자를 다시 검색하는 테스트 함수를 작성하겠습니다.

 

>>> def unicode_test(value): 

  • ...  import unicodedata
  •     ...      name = unicodedata.name(value)
  •  
  •     ...      value2 = unicodedata.lookup(name)
  •  
  • ...  print('value="%s", name="%s", value2="%s"' % (value, name, value2)) ...

일반 ASCII 문자로 시작하는 몇 가지 문자를 사용해 보겠습니다.

 

  • >>> unicode_test('A')
  •     value="A", name="LATIN CAPITAL LETTER A", value2="A"

  • ASCII punctuation:
        >>> unicode_test('$')
  •     value="$", name="DOLLAR SIGN", value2="$"

  • A Unicode currency character:
    >>> unicode_test('\u00a2')
    value="¢", name="CENT SIGN", value2="¢"
    Another Unicode currency character:
    >>> unicode_test('\u20ac')
    value="€", name="EURO SIGN", value2="€"

잠재적으로 발생할 수 있는 유일한 문제는 텍스트를 표시하는 데 사용하는 글꼴의 제한입니다. 모든 글꼴에 모든 유니코드 문자에 대한 이미지가 없는 경우 일부 자리 표시자 문자가 표시될 수 있습니다. 예를 들어, 딩뱃 글꼴의 기호와 같은 스노우맨의 유니코드 기호는 다음과 같습니다.

 

  • >>> unicode_test('\u2603')
    value="☃", name="SNOWMAN", value2="☃"

카페라는 단어를 파이썬 문자열에 저장하려고 합니다. 한 가지 방법은 파일이나 웹 사이트에서 복사하여 붙여넣기하여 다음 작업을 수행하는 것입니다.

 

  •   >>> place = 'café'
  •     >>> place
  •     'café'
  •  

UTF-8 인코딩을 사용한 원본에서 텍스트에 복사하여 붙여넣었기 때문에 가능했습니다.

최종문자를 어떻게 지정할 수 있습니까? E의 문자 색인을 보면, 급성 라틴 소문자 이름 E의 값이 00E9임을 알 수 있습니다. 방금 사용하던 이름() 및 조회() 함수로 확인해 보겠습니다. 먼저 코드를 입력하여 이름을 가져옵니다.

 

>>> unicodedata.name('\u00e9') 'LATIN SMALL LETTER E WITH ACUTE' 

그런 다음 코드를 조회할 이름을 지정합니다.

 >>> unicodedata.lookup('E WITH ACUTE, LATIN SMALL LETTER')

    Traceback (most recent call last):

File "<stdin>", line 1, in <module>
KeyError: "undefined character name 'E WITH ACUTE, LATIN SMALL LETTER'" 

유니코드 문자 이름 색인 페이지에 나열된 이름은 표시에 적합하게 정렬되도록 다시 포맷되었습니다. 이러한 이름을 실제 유니코드 이름(파이썬에서 사용하는 이름)으로 변환하려면 쉼표를 제거하고 쉼표 뒤에 있던 이름의 일부를 처음으로 이동합니다. 따라서 급성 라틴 소문자 E를 급성 라틴 소문자 E로 변경합니다.

 

>>> unicodedata.lookup('LATIN SMALL LETTER E WITH ACUTE') 'é' 

이제 코드 또는 이름으로 문자열 카페를 지정할 수 있습니다.

>>> place = 'caf\u00e9'
>>> place
'café'
>>> place = 'caf\N{LATIN SMALL LETTER E WITH ACUTE}' >>> place 

'café' 

앞의 코드 조각에서 문자열에 직접 é를 삽입했지만 다음을 추가하여 문자열을 만들 수도 있습니다.

 

>>> u_umlaut = '\N{LATIN SMALL LETTER U WITH DIAERESIS}' >>> u_umlaut
'ü'
>>> drink = 'Gew' + u_umlaut + 'rztraminer' 

>>> print('Now I can finally have my', drink, 'in a', place) Now I can finally have my Gewürztraminer in a café 

문자열 렌 함수는 바이트가 아닌 유니코드 문자를 카운트합니다.

>>> len('$')
1
>>> len('\U0001f47b') 1 

Encode and decode with UTF-8 

일반적인 문자열을 처리할 때 파이썬에서 각 유니코드 문자를 저장하는 방법에 대해 걱정할 필요가 없습니다.

그러나 외부와 데이터를 교환할 때는 두 가지 사항이 필요합니다.

 

문자 문자열을 바이트로 인코딩하는 방법

문자 문자열로 바이트를 디코딩하는 방법

 

유니코드에 64,000자 미만의 문자가 있으면 각 유니코드 문자 ID를 2바이트로 저장할 수 있습니다. 불행하게도, 더 있습니다. 각 ID를 3, 4바이트 단위로 인코딩할 수 있지만, 그렇게 하면 공통 텍스트 문자열에 대한 메모리 및 디스크 저장 공간이 3, 4배 증가합니다.

Unix 개발자들에게 친숙한 이름을 가진 Ken Thompson과 Rob Pike는 어느 날 밤 뉴저지의 한 식당에서 UTF-8 동적 인코딩 방식에 서명했다. 유니코드 문자당 1~4바이트를 사용합니다.

 

• ASC용 1바이트Ⅱ

• 대부분의 라틴어에서 파생된 언어(키릴어는 아님)의 경우 2바이트

• 나머지 다국어 평면의 경우 3바이트

• 일부 아시아 언어와 기호를 포함한 나머지 4바이트

 

UTF-8은 Python, Linux 및 HTML의 표준 텍스트 인코딩입니다. 빠르고 완전하며 잘 작동합니다. 만약 당신이 코드 전체에 UTF-8 인코딩을 사용한다면, 삶은 다양한 인코딩에 들어가고 나오는 것보다 훨씬 쉬울 것이다.

 

웹 페이지와 같은 다른 원본에서 복사하여 붙여넣기하여 파이썬 문자열을 만드는 경우, 소스가 UTF-8 형식으로 인코딩되어 있는지 확인하십시오. Latin-1 또는 Windows 1252로 인코딩된 텍스트가 파이썬 문자열로 복사되어 나중에 잘못된 바이트 시퀀스로 돌출되는 것을 볼 수 있습니다.

 

  • Encoding 
  • 문자열을 바이트로 인코딩합니다. 문자열 인코딩() 함수의 첫 번째 인수는 en coding 부호화 이름입니다. 선택사항은 표 7-1에 제시된 것을 포함한다.
  • Table 7-1. Encodings 
  • 'ascii' Good old seven-bit ASCII
    'utf-8' Eight-bit variable-length encoding, and what you almost always want to use 
  • 'latin-1' Also known as ISO 8859-1
    'cp-1252' A common Windows encoding
  • 'unicode-escape' Python Unicode literal format,\uxxxx or\Uxxxxxxxx 

 

  • UTF-8로 인코딩할 수 있습니다. 유니코드 문자열 '\u2603'을 스노우맨 이름에 할당해 보겠습니다.

>>> snowman = '\u2603' 

스노우맨은 내부적으로 저장하는 데 필요한 바이트 수에 관계없이 단일 문자를 가진 파이썬 유니코드 문자열입니다.

 

 >>> len(snowman)

    1

다음으로 이 유니코드 문자를 바이트 순서로 인코딩해 보겠습니다.

>>> ds = snowman.encode('utf-8')

앞서 언급했듯이 UTF-8은 가변 길이 인코딩입니다. 이 경우, 3개를 사용했습니다.

단일 눈사람 유니코드 문자를 인코딩하는 바이트:

 

>>> len(ds)
3
>>> ds b'\xe2\x98\x83' 

이제 len()은 ds가 바이트 변수이기 때문에 바이트 수를 반환합니다.

UTF-8 이외의 인코딩을 사용할 수 있지만 인코딩으로 유니코드 문자열을 처리할 수 없는 경우 오류가 발생합니다. 예를 들어, ASCII 인코딩을 사용하는 경우 유니코드 문자도 유효한 ASCII 문자가 아니면 실패합니다.

  >>> ds = snowman.encode('ascii')

    Traceback (most recent call last):

File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character '\u2603' in position 0: ordinal not in range(128) 

인코딩() 함수는 인코딩 예외를 방지하는 데 도움이 되는 두 번째 인수를 사용합니다. 이전 예에서 볼 수 있는 기본값은 '엄격'입니다. ASC가 아닌 경우 유니코드EncodeError가 발생합니다.II 캐릭터. 다른 인코딩도 있습니다. 인코딩되지 않는 것을 버리려면 '무시'를 사용하십시오.

 

  >>> snowman.encode('ascii', 'ignore')

    b''

알 수 없는 문자를 대체하려면 '바꾸기'를 사용하십시오.

>>> snowman.encode('ascii', 'replace') 

b'?'

유니코드와 같은 파이썬 유니코드 문자 문자열을 만들려면 '백슬래시 바꾸기'를 사용하십시오.

escape:
>>> snowman.encode('ascii', 'backslashreplace') 

b'\\u2603'

유니코드 이스케이프 시퀀스의 인쇄 가능한 버전이 필요한 경우 이 옵션을 사용합니다. 다음은 웹 페이지에서 사용할 수 있는 문자 엔터티 문자열을 생성합니다.

 

 >>> snowman.encode('ascii', 'xmlcharrefreplace')

    b'&#9731;'

 

디코딩

바이트 문자열을 유니코드 문자열로 디코딩합니다. 일부 외부 소스(파일, 데이터베이스, 웹 사이트, 네트워크 API 등)에서 텍스트를 가져올 때마다 바이트 문자열로 인코딩됩니다. 까다로운 부분은 어떤 인코딩이 실제로 사용되었는지 알기 때문에 이를 역방향으로 실행하고 유니코드 문자열을 가져올 수 있습니다.

문제는 바이트 문자열 자체에 사용된 인코딩을 나타내는 것은 없다는 것이다. 나는 앞서 웹사이트에서 복사와 붙여넣기의 위험에 대해 언급했다. 여러분은 아마도 보통 오래된 ASCII 문자가 있어야 하는 홀수 문자로 웹사이트를 방문한 적이 있을 것이다.

'카페' 값을 사용하여 플레이스라는 유니코드 문자열을 만듭니다.

 

>>> place = 'caf\u00e9' >>> place
'café'
>>> type(place) 

<class 'str'>

place_bytes라는 바이트 변수로 UTF-8 형식으로 인코딩합니다.

 

>>> place_bytes = place.encode('utf-8') >>> place_bytes
b'caf\xc3\xa9'
>>> type(place_bytes) 

<class 'bytes'> 

place_bytes는 5바이트입니다. 처음 3개는 ASCII (UTF-8의 강도)와 동일하며, 마지막 2개는 'é'를 인코딩한다. 이제 바이트 문자열을 유니코드 문자열로 다시 디코딩해 보겠습니다.

 

 >>> place2 = place_bytes.decode('utf-8')

    >>> place2

    'café'

UTF-8로 인코딩하고 UTF-8로 디코딩했기 때문에 가능했습니다. 다른 인코딩에서 디코딩하라고 하면 어떨까요?

 

 >>> place3 = place_bytes.decode('ascii')

    Traceback (most recent call last):

File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 3: ordinal not in range(128) 

바이트 값 0xc3이 ASCII에서 잘못되었기 때문에 ASCII 디코더가 예외를 발생시켰습니다. 128 (헥스 80)과 255 (헥스 FF) 사이의 값이 UTF-8과 동일하지는 않지만 합법적인 일부 8비트 문자 집합 인코딩이 있습니다.

 

  >>> place4 = place_bytes.decode('latin-1')

    >>> place4

    'café'

    >>> place5 = place_bytes.decode('windows-1252')

    >>> place5

    'café'

 

Urk. 

이 이야기의 교훈은 가능할 때마다 UTF-8 인코딩을 사용하라는 것이다. 모든 곳에서 작동하고 지원되며 모든 유니코드 문자를 표현할 수 있으며 빠르게 디코딩되고 인코딩됩니다.

 

이 이야기의 교훈은 가능할 때마다 UTF-8 인코딩을 사용하라는 것이다. 모든 곳에서 작동하고 지원되며 모든 유니코드 문자를 표현할 수 있으며 빠르게 디코딩되고 인코딩됩니다.

자세한 정보는

자세한 내용은 다음 링크를 참조하십시오.

 

• 유니코드 HOWTO

• 실용 유니코드

모든 소프트웨어 개발자가 유니코드 문자 집합에 대해 절대적으로 알아야 하는 절대 최소값(변명 없음

파이상자 Handle Missing Keys with setdefault() and defaultdict()

Handle Missing Keys with setdefault() and defaultdict() 

존재하지 않는 키로 사전에 액세스하려고 하면 탁월한 효과를 얻을 수 있습니다. 사전 get() 함수를 사용하여 기본값을 반환하면 예외가 발생하지 않습니다.

setdefault() 함수는 get()와 같지만 키가 없는 경우 사전에 항목을 할당합니다.

 

>>> periodic_table = {'Hydrogen': 1, 'Helium': 2} >>> print(periodic_table)
{'Helium': 2, 'Hydrogen': 1} 

 

키가 사전에 없는 경우 새 값이 사용됩니다.

 

 >>> carbon = periodic_table.setdefault('Carbon', 12)

    >>> carbon

    12

    >>> periodic_table

{'Helium': 2, 'Carbon': 12, 'Hydrogen': 1}

기존 키에 다른 기본값을 할당하려고 하면 원래 값이 반환됩니다.

아무것도 변경되지 않습니다.

 

  >>> helium = periodic_table.setdefault('Helium', 947)

    >>> helium

    2

    >>> periodic_table

    {'Helium': 2, 'Carbon': 12, 'Hydrogen': 1}

 

defaultdict()도 비슷하지만 사전을 만들 때 앞에 있는 모든 새 키의 기본값을 지정합니다. 인수는 함수입니다. 이 예에서는 int()라고 하는 함수 int를 전달하고 정수 0을 반환합니다.

 

>>> from collections import defaultdict >>> periodic_table = defaultdict(int) 

 

이제 결측값은 정수(int)이며 값은 0입니다.

>>> periodic_table['Hydrogen'] = 1
>>> periodic_table['Lead']
0
>>> periodic_table
defaultdict(<class 'int'>, {'Lead': 0, 'Hydrogen': 1}) 

defaultdict() 인수는 누락된 키에 할당할 값을 반환하는 함수입니다. 다음 예에서 no_idea()는 필요할 때 값을 반환하기 위해 실행됩니다.

 

>>> from collections import defaultdict >>>
>>> def no_idea():
... return 'Huh?' 

    ...

    >>> bestiary = defaultdict(no_idea)

    >>> bestiary['A'] = 'Abominable Snowman'

    >>> bestiary['B'] = 'Basilisk'

    >>> bestiary['A']

    'Abominable Snowman'

    >>> bestiary['B']

 'Basilisk'

    >>> bestiary['C']

    'Huh?'

 

int() 함수, list() 함수 또는 dict() 함수를 사용하여 해당 유형의 기본 빈 값을 반환할 수 있습니다. int()는 0을 반환하고 list()는 빈 목록([])을 반환하며 dict()는 빈 사전({})을 반환합니다. 인수를 생략하면 새 키의 초기 값이 없음으로 설정됩니다.

그런데 통화 내에서 람다를 사용하여 기본 설정 함수를 정의할 수 있습니다.

 >>> bestiary = defaultdict(lambda: 'Huh?') >>> bestiary['E']
'Huh?' 

int를 사용하는 것도 자신만의 카운터를 만드는 한 가지 방법입니다.

 

>>> from collections import defaultdict
>>> food_counter = defaultdict(int)
>>> for food in ['spam', 'spam', 'eggs', 'spam']: ... food_counter[food] += 1
...
>>> for food, count in food_counter.items():
... print(food, count)
...
eggs 1
spam 3 

 

앞의 예에서, food_counter가 디폴트딕트 대신 일반 사전이었다면, 파이썬은 초기화되지 않았기 때문에 food_counter[food] 사전 요소를 증가시키려고 할 때마다 예외를 제기했을 것이다. 여기에 표시된 것처럼 추가 작업이 필요했을 것입니다.

 

>>> dict_counter = {}
>>> for food in ['spam', 'spam', 'eggs', 'spam']: 

...
>>> for food, count in dict_counter.items(): ... print(food, count) 

... 

spam 3 eggs 1 

Count Items with Counter() 

카운터 얘기가 나와서 말인데, 표준 라이브러리에는 이전 예제와 같은 작업을 수행하는 라이브러리가 있습니다.

 

>>> from collections import Counter
>>> breakfast = ['spam', 'spam', 'eggs', 'spam'] >>> breakfast_counter = Counter(breakfast)
>>> breakfast_counter
Counter({'spam': 3, 'eggs': 1}) 

most_common() 함수는 모든 요소를 내림차순으로 반환하거나 카운트가 주어진 경우 최상위 카운트 요소만 반환합니다.

 

 >>> breakfast_counter.most_common()

    [('spam', 3), ('eggs', 1)]

    >>> breakfast_counter.most_common(1)

    [('spam', 3)]

 

카운터를 결합할 수 있습니다. 먼저, breakfast_counter에 무엇이 있는지 다시 한 번 살펴보겠습니다.

 

>>> breakfast_counter 

>>> Counter({'spam': 3, 'eggs': 1})

이번에는 점심이라고 불리는 새로운 목록과 점심 카운터라고 불리는 카운터를 만들겠습니다.

 

 >>> lunch = ['eggs', 'eggs', 'bacon']

    >>> lunch_counter = Counter(lunch)

    >>> lunch_counter

    Counter({'eggs': 2, 'bacon': 1})

 

두 카운터를 결합하는 첫 번째 방법은 +를 사용하는 덧셈입니다.

 

>>> breakfast_counter + lunch_counter 

Counter({'spam': 3, 'eggs': 3, 'bacon': 1})

예상하신 대로 -를 사용하여 카운터 하나를 다른 카운터에서 뺍니다.

아침은 안먹고 점심은 안먹어?

 

>>> breakfast_counter - lunch_counter

    Counter({'spam': 3})

좋아요, 그럼 아침으로 먹을 수 없는 점심으로 뭘 먹을 수 있을까요?

 

  >>> lunch_counter - breakfast_counter

    Counter({'bacon': 1, 'eggs': 1})

 

이전의 세트와 마찬가지로 교차로 op‐ erator &:를 사용하여 공통 항목을 얻을 수 있습니다.

 >>> breakfast_counter & lunch_counter

    Counter({'eggs': 1})

교차로는 공통 요소(계란)를 더 낮은 수로 선택했습니다. 이것은 말이 된다: 아침식사는 계란 한 개만 제공했기 때문에, 그것이 일반적인 계산이다.

마지막으로, 유니언 연산자를 사용하여 모든 항목을 가져올 수 있습니다. |:

 

 >>> breakfast_counter | lunch_counter

    Counter({'spam': 3, 'eggs': 2, 'bacon': 1})

 

'계란'이라는 항목은 다시 두 가지 모두에 공통적이었다. 조합은 덧셈과 달리 인원수를 늘리지 않고 더 큰 숫자를 골랐다.

 

Order by Key with OrderedDict() 

이 책의 초기 장에 있는 많은 코드 예제는 사전의 키 순서를 예측할 수 없다는 것을 보여준다. 키 a, b 및 c는 해당 순서로 추가할 수 있지만 키()는 c, a, b를 반환할 수 있다. 여기 이전포스팅에서 용도를 변경한 예가 있습니다.

 

>>> quotes = { 

  •     ...      'Moe': 'A wise guy, huh?',
  •  
  •     ...      'Larry': 'Ow!',
  •  
  • ...  'Curly': 'Nyuk nyuk!', ... }
    >>> for stooge in quotes:
    ... print(stooge)
    ...
    Larry
    Curly
    Moe

OrderedDict()는 키 추가 순서를 기억하고 반복자로부터 동일한 순서로 반환합니다. (키, 값) 튜플 순서에서 OrderedDict를 만들어 보십시오.

 

  • >>> from collections import OrderedDict >>> quotes = OrderedDict([
  • Stack + Queue == deque

데크(데크 발음)는 스택과 큐의 기능을 모두 갖춘 이중 종단 큐입니다. 시퀀스의 양쪽 끝에서 항목을 추가 및 삭제할 때 유용합니다. 여기, 우리는 단어 양쪽 끝에서 중간까지 페일린 드롬인지 알아봅니다. popleft() 함수는 데크에서 맨 왼쪽 항목을 제거했다가 반환합니다. pop()은 맨 오른쪽 항목을 제거했다가 반환합니다. 함께, 그들은 끝에서 중간까지 일을 합니다. 끝 문자가 일치하는 한 중간에 도달할 때까지 계속 터집니다.

 

>>> def palindrome(word): 

...

>>> palindrome('a')

True

from collections import deque dq = deque(word)
while len(dq) > 1: 

if dq.popleft() != dq.pop(): return False 

return True 

    >>> palindrome('racecar')

    True

    >>> palindrome('')

    True

    >>> palindrome('radar')

    True

    >>> palindrome('halibut')

    False

 

저는 이것을 단순한 데크의 삽화로 사용했습니다. 만약 당신이 빠른 회문 체커를 원한다면, 단지 문자열을 그것의 반대와 비교하는 것이 훨씬 더 간단할 것이다. Python에는 문자열에 대한 역함수가 없지만 여기에 표시된 것처럼 슬라이스로 문자열을 역방향으로 사용할 수 있는 방법이 있습니다.

 

>>> def another_palindrome(word): ... return word == word[::-1] ...
>>> another_palindrome('radar') True 

    >>> another_palindrome('halibut')

    False

 

Iterate over Code Structures with itertools 

이터툴스는 특수 목적 반복기 기능을 포함한다. 각각 ...에 대해 a 내에서 호출하면 한 번에 하나의 항목을 반환합니다. 호출 사이의 상태를 기억합니다.

chain은 마치 하나의 참을 수 있는 것처럼 그 논거를 통과한다.

 

>>> import itertools
>>> for item in itertools.chain([1, 2], ['a', 'b']): ... print(item)
...
1
2
a
b 

cycle()은 무한 반복자로, 그 인수를 순환한다.

>>> import itertools
>>> for item in itertools.cycle([1, 2]): ... print(item)
...
1
2
1
2
.
.
. 

기타 등등.

누적은 누적된 값을 계산합니다. 기본적으로 합계가 계산됩니다.

>>> import itertools
>>> for item in itertools.accumulate([1, 2, 3, 4]): ... print(item)
...
1
3
6
10 

누적()할 두 번째 인수로 함수를 제공할 수 있으며, 추가 대신 이 인수가 사용됩니다. 함수는 두 개의 인수를 사용하여 단일 결과를 반환해야 합니다. 이 예제에서는 누적 제품을 계산합니다.

>>> import itertools
>>> def multiply(a, b):
... returna*b
...
>>> for item in itertools.accumulate([1, 2, 3, 4], multiply): ... print(item)
...
1
2
6
24 

이터툴즈 모듈에는 더 많은 기능이 있으며, 특히 필요에 따라 시간을 절약할 수 있는 조합과 순열에 대한 기능이 있습니다.

 

Print Nicely with pprint() 

모든 예제는 인쇄()(또는 대화형 인터프리터의 변수 이름만)를 사용하여 인쇄했습니다. 때때로, 그 결과는 읽기 어렵다. 우리는 print 와 같은 예쁜 프린터가 필요하다.

 

>>> from pprint import pprint >>> quotes = OrderedDict([ 

  • ...      ('Moe', 'A wise guy, huh?'),
  •  
  •     ...      ('Larry', 'Ow!'),
  •  
  •     ...      ('Curly', 'Nyuk nyuk!'),
  •     ...     ])

  • >>>

그냥 오래된 인쇄물은 물건들을 그냥 저기에 버립니다.

 

  • >>> print(quotes)
    OrderedDict([('Moe', 'A wise guy, huh?'), ('Larry', 'Ow!'), ('Curly', 'Nyuk nyuk!')]) 

그러나 pprint()는 가독성을 높이기 위해 요소를 정렬하려고 합니다.

 

  •     >>> pprint(quotes)
  •     {'Moe': 'A wise guy, huh?',
  •   'Larry': 'Ow!',
  •     'Curly': 'Nyuk nyuk!'}

More Batteries: Get Other Python Code 

때때로, 표준 라이브러리는 여러분이 필요로 하는 것을 가지고 있지 않거나, 아주 올바른 방법으로 그것을 하지 않습니다. 오픈 소스, 타사 파이썬 소프트웨어가 전 세계에 걸쳐 있습니다. 좋은 리소스는 다음과 같습니다.

  • • PyPi (also known as the Cheese Shop, after an old Monty Python skit)
  • • github
  • • readthedocs

activestate에서 더 작은 코드 예제를 많이 볼 수 있습니다.

 

이 책에 있는 거의 모든 파이썬 코드는 모든 내장 및 표준 라이브러리를 포함하는 컴퓨터에 표준 파이썬 설치를 사용합니다. 외부 패키지는 다음과 같은 위치에 있습니다. 1장에서 요청을 언급했으며, 222페이지의 "표준 라이브러리 너머: 요청"에서 자세한 내용을 설명합니다. 부록 D는 다른 많은 너트 앤 볼트 개발 세부사항과 함께 타사 파이썬 소프트웨어를 설치하는 방법을 보여준다.

 

해야 할 일

5.1. zoo.py이라는 파일을 만듭니다. 여기에서 '매일 9-5 열기' 문자열을 인쇄하는 hours()라는 함수를 정의합니다. 그런 다음 대화형 통역기를 사용하여 동물원 모듈을 가져오고 시간() 기능을 호출합니다.

5.2. 대화형 통역기에서 동물원 모듈을 menagerie로 가져오고 시간() 기능을 호출한다.

5.3. 통역실에 머무르면서 동물원으로부터 직접 시간() 기능을 가져와 전화한다.

5.4. 시간() 기능을 정보로 가져와 호출합니다.

5.5. 키-값 쌍 'a'가 1, 'b': 2, 'c'인 일반 사전을 만듭니다.

3번, 그리고 인쇄하세요.

5.6. 5.5에 나열된 동일한 쌍으로 팬시라고 불리는 OrderedDict를 만들어 인쇄합니다.

일반과 같은 순서로 인쇄되었습니까?

5.7. dict_of_lists라는 디폴트딕트를 만들어 인수 목록을 전달합니다. 목록을 dict_of_lists['a'] 만들고 번의 할당으로 'something for a' 값을 추가합니다. dict_of_lists['a'] 인쇄합니다.