Что такое python: чем он хорош, где пригодится и как его выучить

Datatype mapping callbacks through DataHandler

The DataHandler interface has three methods for handling type
mappings. They are called at two different times, one when fetching and
the other when binding objects for use in a prepared statement. I have
chosen this architecture for type binding because I noticed a number
of discrepancies in how different JDBC drivers handled database types,
in particular the additional types available in later JDBC versions.

public void preExecute(Statement stmt) throws SQLException;
A callback prior to each execution of the statement. If the statement
is a PreparedStatement (created when parameters are sent to the
execute method), all the parameters will have been set.
public void postExecute(Statement stmt) throws SQLException;
A callback after successfully executing the statement. This is
particularly useful for cases such as auto-incrementing columns
where the statement knows the inserted value.
public String getMetaDataName(String name);
A callback for determining the proper case of a name used in a
DatabaseMetaData method, such as getTables(). This is particularly
useful for Oracle which expects all names to be upper case.
public PyObject getRowId(Statement stmt) throws SQLException;
A callback for returning the row id of the last insert statement.
public Object getJDBCObject(PyObject object, int type);
This method is called when a PreparedStatement is created through
use of the execute method. When the parameters are being bound to
the statement, the DataHandler gets a callback to map the type. This
is only called if type bindings are present.
public Object getJDBCObject(PyObject object);
This method is called when no type bindings are present during the
execution of a PreparedStatement.
public PyObject getPyObject(ResultSet set, int col, int type);
This method is called upon fetching data from the database. Given
the JDBC type, return the appropriate PyObject subclass from the
Java object at column col in the ResultSet set.

Event Properties

In standard Java, the event handlers for a widget are specified by passing in an instance of a class that implements the appropriate interface. This is the only reasonable approach to take in a language that doesn’t have first-class functions. In Jython, for every event listener supported by a class, there will be a property added to the class for each method supplied by the event listener class. These properties can be set to give a function to be called when the appropriate event occurs.

The standard Java style for setting an event listener is shown below:

class action(awt.event.ActionListener):
    def actionPerformed(self,event):
        java.lang.System.exit(0)

button = awt.Button("Close Me!")
button.addActionListener(action())

This can be written in a more Pythonesque (and compact) style by using event properties as follows:

Java 1.1

To be honest the unloading support that jython can offer under java
1.1 (given the absence of weak/soft-refs) is error-prone and anything
serious would require «too much» caution, but this should not be a real
issue. Support is offered only for «jreload» needs, in these forms:

# Before reload(X) one can issue X.unload(). X.unload() discards all the
entries for the old versions of the classes in X. This is safe only if
all python subclasses and all instances of them have been destroyed.
# One can «extract» the information needed in order to discard the
entries for the versions actually present in X at a later point (after
a whole series of reloads):

u_t1() is safe only if at that point all subclasses/instances of the
involved versions have been destroyed.

API

dbexts will default to looking for a file named ‘dbexts.ini’ in the same
directory as dbexts.py but can optionally be passed a filename to the
cfg attribute.

__init__(self, dbname=None, cfg=None, resultformatter=format_resultset,
autocommit=1)
   The initialization method for the dbexts class. If dbname is None,
   the default connection, as specified in the cfg file will be used.

isql(self, sql, params=None, bindings=None, maxrows=None)
   Interactively execute sql statement. If self.verbose is true, then
   the results (if any) are displayed using the result formatting
   method. If maxrows is specified, only maxrows are displayed.

raw(self, sql, params=None, bindings=None, delim=None, comments=comments)
   Executes the sql statement with params and bindings as
   necessary. Returns a tuple consisting of (headers, results).

schema(table, full=0, sort=1)
   Displays the schema (indicies, foreign keys, primary keys and
   columns) for the table parameter. If full is true, also compute
   the exported (or referenced) keys. If sort is true (the default),
   sort the column names.

   >>> d.schema("store")
   Table
     store

   Primary Keys
     store_id {store_3}

   Imported (Foreign) Keys
     location (city.city_id) {store_7}

   Exported (Referenced) Keys
     store_id (site_store.store_id) {site_store_8}

   Columns
     location           int(4), non-nullable
     store_id           serial(4), non-nullable
     store_name         varchar(32), non-nullable

   Indices
     unique index {523_8115} on (store_id)
     unique index {store_ix_1} on (store_name)
   >>>

table(table=None, types=("TABLE",), owner=None, schema=None)
   If no table argument, displays a list of all tables. If a table
   argument, displays the columns of the given table.

proc(self, proc=None, owner=None, schema=None)
   If no proc argument, displays a list of all procedures. If a proc
   argument, displays the parameters of the given procedure.

bcp(src, table, where='(1=1)', parameters=[], selective=[], ignorelist=[],
   autobatch=0)
   Bulk Copy from one database/table to another. The current instance
   of dbexts is the source database to which the results of the query
   on the foreign database will be inserted. An optional where clause
   can narrow the number of rows to be copied.

The following are generally not called since isql and raw can handle
almost all cases.

Calling Java Methods and Functions

Java classes have both static and instance methods this makes them
behave much like a cross between a Python module and class. As a user,
you should rarely need to be concerned with this difference.

Java methods and functions are called just exactly like their Python
counterparts. There is some automatic type coercion that goes on both for
the types being passed in and for the value returned by the method. The
following table shows how Python objects are coerced to Java objects
when passed as arguments in a function call. The Java Types show the
expected Java type for the argument, and the Allowed Python Types shows
what Python objects can be converted to the given Java type. Notice the
special behavior of String’s when a java.lang.Object is expected. This
behavior might change if it is shown to cause problems.

Java Types Allowed Python Types
char String (must have length 1)
boolean Integer (true = nonzero)
byte, short, int, long Integer
float, double Float
java.lang.String, byte[], char[] String
java.lang.Class Class
or JavaClass
(only if class subclasses from exactly one Java class; mutiple inheritance from more than one Java
class is now illegal)
Foo[] Array (must contain objects of class or subclass of Foo)
java.lang.Object String->java.lang.String, all others unchanged
org.python.core.PyObject All unchanged
Foo Instance->Foo (if Instance is subclass of Foo);
JavaInstance -> Foo (if JavaInstance is instance of Foo or subclass)

Returned values from a Java method are also possibly coerced back to an
object that is more readily usable in Python. The following table shows
those coercions.

Overloaded Java Method Signatures

Java methods are allowed to be overloaded for different signatures (types
and number of arguments). When different versions of the method differ
in the number of arguments that they expect, the appropriate method can
be easily determined from the number of arguments passed to the method.

When the difference is instead in the types of the arguments, more
work is required. The possible signatures are sorted in a consistent
order that should ensure the appropriate method is chosen first. TBD:
document this order!

If you need to call a Java method with a particular signature and this
is not happening in the easy way, you can use the following workaround:

Assume that foo has two methods, «void foo(int x); void foo(byte x);». To
call the second method you could write the following:

from java.lang import Byte
foo(Byte(10))

I’m not convinced that any better solution to this problem is possible.

Какие компании используют Python

В основном Python используется стартапами и компаниями, которые разрабатывают крупные проекты. Вот лишь часть огромного списка:

  • Alphabet использует язык для скраппинга в поисковике Google и реализации сервиса YouTube;
  • One Laptop Per Child — для разработки интерфейса и модели функционирования;
  • BitTorrent — для реализации сетей peer-to-peer;
  • Агентство национальной безопасности США — для шифрования и анализа разведданных;
  • ESRI — как инструмент настройки геоинформационных программ;
  • Maya — для создания мультипликации;
  • Pixar, Industrial Light & Magic — для создания анимационных фильмов;
  • Intel, Cisco, HP, Seagate, Qualcomm и IBM — для тестирования;
  • JPMorgan Chase, UBS, Getco и Citadel — для прогнозирования финансового рынка;
  • NASA, Los Alamos, Fermilab, JPL — для научных вычислений;
  • iRobot — для разработки коммерческих роботизированных устройств;
  • IronPort — для реализации почтового сервера.

Using a JNDI lookup

It is possible for zxJDBC to use a Connection found through a JNDI
lookup. This is particularly useful in an application server (such as when
using PyServlet). The bound object can be either a String, Connection,
DataSource or ConnectionPooledDataSource. The lookup will figure out
the instance type and access the Connection accordingly,

The only required argument is the JNDI lookup name. All keyword arguments
will be converted to their proper Context field value if the keyword
matches one of the constants. If a field name does not exist for the
keyword, it will passed as declared. The resulting environment will be
used to build the InitialContext.

This example uses the simple Sun FileSystem JNDI reference
implementation. Please consult the JNDI implementation you intend to use
for the InitialContextFactory classname as well as the connection URL.

Major new features of the 3.8 series, compared to 3.7

  • PEP 572, Assignment expressions
  • PEP 570, Positional-only arguments
  • PEP 587, Python Initialization Configuration (improved embedding)
  • PEP 590, Vectorcall: a fast calling protocol for CPython
  • PEP 578, Runtime audit hooks
  • PEP 574, Pickle protocol 5 with out-of-band data
  • Typing-related: PEP 591 (Final qualifier), PEP 586 (Literal types), and PEP 589 (TypedDict)
  • Parallel filesystem cache for compiled bytecode
  • Debug builds share ABI as release builds
  • f-strings support a handy specifier for debugging
  • is now legal in blocks
  • on Windows, the default event loop is now
  • on macOS, the spawn start method is now used by default in
  • can now use shared memory segments to avoid pickling costs between processes
  • is merged back to CPython
  • is now 40% faster
  • now uses Protocol 4 by default, improving performance

There are many other interesting changes, please consult the «What’s New» page in the documentation for a full list.

Examples from the Python standard library

env_base is only used on these lines, putting its assignment on the if
moves it as the «header» of the block.

  • Current:

    env_base = os.environ.get("PYTHONUSERBASE", None)
    if env_base:
        return env_base
    
  • Improved:

    if env_base := os.environ.get("PYTHONUSERBASE", None):
        return env_base
    

Avoid nested if and remove one indentation level.

  • Current:

    if self._is_special:
        ans = self._check_nans(context=context)
        if ans:
            return ans
    
  • Improved:

    if self._is_special and (ans := self._check_nans(context=context)):
        return ans
    

Code looks more regular and avoid multiple nested if.
(See Appendix A for the origin of this example.)

  • Current:

    reductor = dispatch_table.get(cls)
    if reductor:
        rv = reductor(x)
    else:
        reductor = getattr(x, "__reduce_ex__", None)
        if reductor:
            rv = reductor(4)
        else:
            reductor = getattr(x, "__reduce__", None)
            if reductor:
                rv = reductor()
            else:
                raise Error(
                    "un(deep)copyable object of type %s" % cls)
    
  • Improved:

    if reductor := dispatch_table.get(cls):
        rv = reductor(x)
    elif reductor := getattr(x, "__reduce_ex__", None):
        rv = reductor(4)
    elif reductor := getattr(x, "__reduce__", None):
        rv = reductor()
    else:
        raise Error("un(deep)copyable object of type %s" % cls)
    

tz is only used for s += tz, moving its assignment inside the if
helps to show its scope.

  • Current:

    s = _format_time(self._hour, self._minute,
                     self._second, self._microsecond,
                     timespec)
    tz = self._tzstr()
    if tz:
        s += tz
    return s
    
  • Improved:

    s = _format_time(self._hour, self._minute,
                     self._second, self._microsecond,
                     timespec)
    if tz := self._tzstr():
        s += tz
    return s
    

Java Classes Unloading

One would expect that no longer referenced java classes would be unloaded,
but the situation is not that simple.

In order to give a python-class-like view on python side and for
implementation reasons jython wraps java classes (in instances of
org.python.core.PyJavaClass). Clearly the mapping from java classes to
their wrapped version should be unique (e.g. to guarantee == and ‘is’
semantic). So jython keeps this mapping in an internal table. This is
also good because building the wrappers is expensive.

Note: Typically one should care about java classes unloading only for
very dynamic applications, like IDEs or long-running apps, that would
go out memory if old versions of reloaded classes would not be collected.

Clearly the entries somehow block unloading. On the other hand java
classes unloading is just a memory consumption optimization (and as such
is it presented in Java Language Specification). Actual jvms clearly
support this. JPython simply kept the entries in the table forever but
Jython and «jreload» try to make unloading possible.

Note: java never unloads system classes (java.* etc) nor classes from
classpath. Further Jython cannot unload sys.path java classes. So
the whole unload issue makes sense only with «jreload» or custom
class-loaders.
Java 2 and jython internalTablesImpl option

Under java2 jython offers table implementations that exploit soft/weak
references in order to discard entries (when this is OK) for unloading.

A possible policy would be to keep an entry as long as the corresponding
java class is still referenced outside the table (both by java or jython
code). But this one cannot be implemented. So entries are kept as long as
the wrapped version is still in use.
These implementations can be chosen trough
python.options.internalTablesImpl registry option. Note: they only
influence classes unloading, there is no need and reason to use them,
unless one depends on class unloading to avoid memory leakage.

internalTablesImpl = weak — Sets implementation using weak-refs. Table
entries for not referenced (outside the table) wrapped versions are
«discarded» at garbage collection points. If a class or some of its
instances are continuously passed from java to jython side, but no
long-living reference to it is kept from jython side, this can imply a
performance penalty (rebuilding the wrapped version is expensive). On
the other hand this is a good setting for testing if unloading actually
happens or some references hunting around prevent it.

Properties

Jython uses JavaBean properties to make it easier to interact with most Java classes. These properties can be used as normal object attributes, and can also be specified to the class constructor as keyword arguments (this idea is stolen from TkInter where it seems to work extremely well).

These properties are generated automatically using the JavaBean Introspector which identifies properties either from common design patterns, or from explicitly specified BeanInfo.

As a first example, consider the case where you wish to create a button that is disabled.

The first example shows how you would do this in the typical Java fashion:

b = awt.Button()
b.setEnabled(0)

The second example shows how enabled can be set as a property:

b = awt.Button()
b.enabled = 0

The final example sets this property at instantiation time using a keyword argument:

Example

The following example should help make things clearer: (its files should
be present in the jython Demo dir)
# Demo/jreload/example.jar contains example.Version (source) and
example.PrintVer (source)
# Demo/jreload/_xample contains a slightly modified version of
example.Version (source)

>>> import sys
>>> import os
>>> import jreload
>>> def xp(name): return os.path.join(sys.prefix,'Demo/jreload/'+name)
# builds a path under 'Demo/jreload'
...
>>> X=jreload.makeLoadSet('X',)
>>> from X import example
>>> dir(example)

>>> X.example.Version
<jclass example.Version at 6781345>
>>> from X.example import * # works but in general import * from java
pkgs is not for production code
>>> v=Version(1)
>>> PrintVer.print(v)
version 1
>>> os.rename(xp('_xample'),xp('example')) # _xample becomes example,
hiding and "patching" jar contents
>>> jreload.reload(X) # (re)loads example dir example.Version and
jar example.PrintVer
<java load-set X>
>>> nv2=example.Version(2)
>>> example.PrintVer.print(nv2)
new version 2
>>> PrintVer.print(nv2)
Traceback (innermost last):
  File "<console>", line 1, in ?
TypeError: print(): 1st arg can't be coerced to example.Version
>>> example.PrintVer.print(v)
Traceback (innermost last):
  File "<console>", line 1, in ?
TypeError: print(): 1st arg can't be coerced to example.Version
>>> os.rename(xp('example'),xp('_xample'))

Note

Differently from python packages reload, load-sets reload the
complete hosted hierarchy.

Note

Class versions across reloads are not interoperable.

And now for something completely different

>
Graham Chapman
: I think all rightthinking people in this country are sick and tired of being told that ordinary, decent people are fed up in this country with being sick and tired.
All: Yes, yes…
Graham Chapman: I’m certainly not! And I’m sick and tired of being told that I am.
Mrs. Havoc-Jones: Well, I meet a lot of people and I’m convinced that the vast majority of wrongthinking people are right.
Eric Idle: That seems like a consensus there.

Version Operating System Description MD5 Sum File Size GPG
Gzipped source tarball Source release 4388c20bb59248a52adcaec7ce4a581c 24063850 SIG
XZ compressed source tarball Source release 5997ad4840d00bd6321e5102f0bae008 17902996 SIG
macOS 64-bit installer Mac OS X for OS X 10.9 and later fe18361ebdcf2a738679b189ac83e51d 30114709 SIG
Windows help file Windows dade3016b80bb8b5928ee227f7415fc2 8572090 SIG
Windows x86-64 embeddable zip file Windows for AMD64/EM64T/x64 17f75fd6cd5b554ff478d923b22a0f87 8176510 SIG
Windows x86-64 executable installer Windows for AMD64/EM64T/x64 17069c3a06cd44663d23d95d820f65e1 27812576 SIG
Windows x86-64 web-based installer Windows for AMD64/EM64T/x64 168644bb1d570bda4bac81a8d0d5ea13 1364128 SIG
Windows x86 embeddable zip file Windows b86b739d84c2d4eba2ceaff57e074afd 7330372 SIG
Windows x86 executable installer Windows b674fb697db9394fcf7bd39ab17ed024 26745552 SIG
Windows x86 web-based installer Windows d4b1f174d4a769500bbd21710bba6cb0 1326272 SIG

2.1.1. История создания¶

Разработка языка Python была начата в конце 1980-х годов сотрудником голландского института CWI (Центр математики и информатики, голл. Centrum Wiskunde & Informatica) Гвидо ван Россумом (англ. Guido van Rossum), на основе языка ABC (Рисунок 2.1.1). В феврале 1991 года Гвидо опубликовал исходный текст в группе новостей alt.sources.

Рисунок 2.1.1 — Гвидо ван Россум на конференции в 2006 г.

О создании Python Гвидо ван Россум написал в 1996 г.:

В настоящее время Гвидо работает в компании Dropbox, покинув в декабре 2012 года корпорацию Google (2005-2012). Имея статус «великодушного пожизненного диктатора» проекта — он продолжает наблюдать за процессом разработки Python, принимая окончательные решения, когда это необходимо (не менее 50% рабочего времени по договоренности с DropBox).

Появившись сравнительно поздно, Python создавался под влиянием множества языков программирования. Так, например, влияние оказали такие языки, как:

  • ABC: отступы для группировки операторов, высокоуровневые структуры данных;

  • Modula-3: пакеты, модули;

  • С, C++: некоторые синтаксические конструкции;

  • Smalltalk: ООП;

  • Java: обработка исключений и др.

Большая часть других особенностей Python (например, байт-компиляция исходного кода) также была реализована ранее в других языках.

Развитие языка происходит согласно четко регламентированному процессу создания, обсуждения, отбора и реализации документов (Python Enhancement Proposal) — предложений по развитию Python.

В 2008 году, после длительного тестирования, вышла первая версия Python 3000 (или Python 3.0, также используется сокращение Py3k). В Python 3000 устранены многие недостатки архитектуры с максимально возможным (но не полным) сохранением совместимости со старыми версиями Python. На сегодня поддерживаются обе ветви развития (Python 3.x и 2.x) (сравнение и рекомендации), однако получать новый функционал будет только версия 3 .

Ключевые вехи развития языка приведены в Таблице 2.1.1.

Таблица 2.1.1 — Основные вехи развития языка Python

Ветвь (дата выхода)

Актуальная версия (дата выхода) (могла устареть)

Python 0.9.0 (1991-02)

Python 0.9.0 (1991-02)

Python 2.x (2000-10-16)

Python 2.7.11 (2015-12-05)

Python 3.x (2008-12-03)

Python 3.4.5 (2016-06-27)

Python 3.5.2 (2016-06-27)

Python 3.6.1 (2017-03-21)

На Видео 2.1.1 и 2.1.2 автор языка рассказывает об истории создания и развития Python (англ.).

Видео 2.1.1 — Guido van Rossum: The Early Years of Python

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector