如何调试Flask应用

问题:如何调试Flask应用

您打算如何调试Flask中的错误?打印到控制台?向页面闪现消息?还是有一个更强大的选项可用来找出出现问题时发生的情况?

How are you meant to debug errors in Flask? Print to the console? Flash messages to the page? Or is there a more powerful option available to figure out what’s happening when something goes wrong?


回答 0

出现错误时,以开发模式运行该应用程序将在浏览器中显示交互式回溯和控制台。要在开发模式下运行,请设置FLASK_ENV=development环境变量,然后使用flask run命令(请记住也指向FLASK_APP您的应用程序)。

对于Linux,Mac,Windows的Linux子系统,Windows的Git Bash等:

export FLASK_APP=myapp
export FLASK_ENV=development
flask run

对于Windows CMD,使用set而不是导出:

set FLASK_ENV=development

对于PowerShell,请使用$env

$env:FLASK_ENV = "development"

在Flask 1.0之前,它是由FLASK_DEBUG=1环境变量控制的。

如果您使用的是app.run()方法而不是flask run命令,请传递debug=True以启用调试模式。

不管开发模式如何,都将回溯打印到运行服务器的终端。

如果您使用的是PyCharm,VS Code等,则可以利用其调试器逐步使用带有断点的代码。运行配置可以指向调用app.run(debug=True, use_reloader=False)venv/bin/flask脚本,也可以将其指向脚本并像在命令行中一样使用它。您可以禁用重新加载器,但是重新加载将终止调试上下文,并且您将不得不再次捕获断点。

您还可以通过set_trace在要开始调试的视图中调用来使用pdb,pudb或其他终端调试器。


确保不要使用太宽的积木。将所有代码都包含在“包罗万象”中try... except...将使您想要调试的错误静音。一般来说,这是不必要的,因为Flask已经可以通过显示调试器或500错误并将回溯打印到控制台来处理异常。

Running the app in development mode will show an interactive traceback and console in the browser when there is an error. To run in development mode, set the FLASK_ENV=development environment variable then use the flask run command (remember to point FLASK_APP to your app as well).

For Linux, Mac, Linux Subsystem for Windows, Git Bash on Windows, etc.:

export FLASK_APP=myapp
export FLASK_ENV=development
flask run

For Windows CMD, use set instead of export:

set FLASK_ENV=development

For PowerShell, use $env:

$env:FLASK_ENV = "development"

Prior to Flask 1.0, this was controlled by the FLASK_DEBUG=1 environment variable instead.

If you’re using the app.run() method instead of the flask run command, pass debug=True to enable debug mode.

Tracebacks are also printed to the terminal running the server, regardless of development mode.

If you’re using PyCharm, VS Code, etc., you can take advantage of its debugger to step through the code with breakpoints. The run configuration can point to a script calling app.run(debug=True, use_reloader=False), or point it at the venv/bin/flask script and use it as you would from the command line. You can leave the reloader disabled, but a reload will kill the debugging context and you will have to catch a breakpoint again.

You can also use pdb, pudb, or another terminal debugger by calling set_trace in the view where you want to start debugging.


Be sure not to use too-broad except blocks. Surrounding all your code with a catch-all try... except... will silence the error you want to debug. It’s unnecessary in general, since Flask will already handle exceptions by showing the debugger or a 500 error and printing the traceback to the console.


回答 1

您可以按如下所述app.run(debug=True)用于Werkzeug调试器 编辑,我应该知道。

You can use app.run(debug=True) for the Werkzeug Debugger edit as mentioned below, and I should have known.


回答 2

1.1.x文档中,您可以通过将环境变量导出到Shell提示符来启用调试模式:

export FLASK_APP=/daemon/api/views.py  # path to app
export FLASK_DEBUG=1
python -m flask run --host=0.0.0.0

From the 1.1.x documentation, you can enable debug mode by exporting an environment variable to your shell prompt:

export FLASK_APP=/daemon/api/views.py  # path to app
export FLASK_DEBUG=1
python -m flask run --host=0.0.0.0

回答 3

人们还可以使用Flask Debug Toolbar扩展程序来获取嵌入在渲染页面中的更多详细信息。

from flask import Flask
from flask_debugtoolbar import DebugToolbarExtension
import logging

app = Flask(__name__)
app.debug = True
app.secret_key = 'development key'

toolbar = DebugToolbarExtension(app)

@app.route('/')
def index():
    logging.warning("See this message in Flask Debug Toolbar!")
    return "<html><body></body></html>"

启动应用程序,如下所示:

FLASK_APP=main.py FLASK_DEBUG=1 flask run

One can also use the Flask Debug Toolbar extension to get more detailed information embedded in rendered pages.

from flask import Flask
from flask_debugtoolbar import DebugToolbarExtension
import logging

app = Flask(__name__)
app.debug = True
app.secret_key = 'development key'

toolbar = DebugToolbarExtension(app)

@app.route('/')
def index():
    logging.warning("See this message in Flask Debug Toolbar!")
    return "<html><body></body></html>"

Start the application as follows:

FLASK_APP=main.py FLASK_DEBUG=1 flask run

回答 4

如果您使用的是Visual Studio Code,请替换

app.run(debug=True)

app.run()

当打开内部调试器禁用VS Code调试器时,它会出现。

If you’re using Visual Studio Code, replace

app.run(debug=True)

with

app.run()

It appears when turning on the internal debugger disables the VS Code debugger.


回答 5

如果要调试flask应用程序,则只需转到flask应用程序所在的文件夹。不要忘了激活您的虚拟环境,并将控制台行中的行更改“ mainfilename”粘贴到flask主文件。

export FLASK_APP="mainfilename.py"
export FLASK_DEBUG=1
python -m flask run --host=0.0.0.0

启用flask应用程序的调试器后,几乎所有错误都会打印在控制台或浏览器窗口上。如果您想弄清楚发生了什么,可以使用简单的打印语句,也可以将console.log()用于javascript代码。

If you want to debug your flask app then just go to the folder where flask app is. Don’t forget to activate your virtual environment and paste the lines in the console change “mainfilename” to flask main file.

export FLASK_APP="mainfilename.py"
export FLASK_DEBUG=1
python -m flask run --host=0.0.0.0

After you enable your debugger for flask app almost every error will be printed on the console or on the browser window. If you want to figure out what’s happening, you can use simple print statements or you can also use console.log() for javascript code.


回答 6

python-dotenv在虚拟环境中安装。

在项目根目录中创建一个.flaskenv。用项目根目录,是指包含您的app.py文件的文件夹

在此文件中写入以下内容:

FLASK_APP=myapp 
FLASK_ENV=development

现在发出以下命令:

flask run

Install python-dotenv in your virtual environment.

Create a .flaskenv in your project root. By project root, I mean the folder which has your app.py file

Inside this file write the following:

FLASK_APP=myapp 
FLASK_ENV=development

Now issue the following command:

flask run

回答 7

要在Flask中激活调试模式,您只需FLASK_DEBUG=1CMDWindows 上键入set 并FLASK_DEBUG=1在Linux terminal上导出,然后重新启动您的应用程序就可以了!

To activate debug mode in flask you simply type set FLASK_DEBUG=1 on your CMD for windows and export FLASK_DEBUG=1 on Linux termial then restart your app and you are good to go!!


回答 8

快速提示-如果您使用的是PyCharm,请转到Edit Configurations=> Configurations并启用FLASK_DEBUG复选框,然后重新启动Run

Quick tip – if you use a PyCharm, go to Edit Configurations => Configurations and enable FLASK_DEBUG checkbox, restart the Run.


回答 9

在开发环境中使用记录器和打印语句,在生产环境中可以进行岗哨。

Use loggers and print statements in the Development Environment, you can go for sentry in case of production environments.


回答 10

对于Windows用户:

打开Powershell并cd进入您的项目目录。

在Powershell中使用这些突击队,其他所有东西在Powershell中将无法使用。

$env:FLASK_APP = "app"  
$env:FLASK_ENV = "development"

For Windows users:

Open Powershell and cd into your project directory.

Use these commandos in Powershell, all the other stuff won’t work in Powershell.

$env:FLASK_APP = "app"  
$env:FLASK_ENV = "development"

回答 11

如果您在本地运行它并希望能够逐步执行代码:

python -m pdb script.py

If you are running it locally and want to be able to step through the code:

python -m pdb script.py


SQLAlchemy:引擎,连接和会话的区别

问题:SQLAlchemy:引擎,连接和会话的区别

我使用SQLAlchemy并至少有三个实体:enginesession并且connection,其中有execute方法,所以如果我如想选择所有记录table我能做到这一点

engine.execute(select([table])).fetchall()

还有这个

connection.execute(select([table])).fetchall()

甚至这个

session.execute(select([table])).fetchall()

-结果将是相同的。

据我了解,如果有人使用engine.executeconnection,它会创建,打开session(Alchemy会为您处理)并执行查询。但是,执行此任务的这三种方式之间是否存在全局差异?

I use SQLAlchemy and there are at least three entities: engine, session and connection, which have execute method, so if I e.g. want to select all records from table I can do this

engine.execute(select([table])).fetchall()

and this

connection.execute(select([table])).fetchall()

and even this

session.execute(select([table])).fetchall()

– the results will be the same.

As I understand it, if someone uses engine.execute it creates connection, opens session (Alchemy takes care of it for you) and executes the query. But is there a global difference between these three ways of performing such a task?


回答 0

单行概述:

的行为execute()是在所有情况下相同,但它们是3种不同的方法,在EngineConnectionSession类。

到底是什么execute()

要了解行为,execute()我们需要调查Executable该类。Executable是所有“语句”类型对象的超类,包括select(),delete(),update(),insert(),text()-用最简单的词来说,Executable是SQLAlchemy支持的SQL表达式构造。

在所有情况下,该execute()方法均采用SQL文本或构造的SQL表达式,即SQLAlchemy支持的各种SQL表达式构造,并返回查询结果(ResultProxya-包装DB-API游标对象以更轻松地访问行列。)


为了进一步澄清(仅用于概念澄清,不建议使用方法)

除了Engine.execute()(无连接执行),Connection.execute()和之外Session.execute(),还可以execute()直接在任何Executable构造上使用。该Executable班有它自己的执行execute()-每个正式文件作为,对什么人一行说明execute()确实是“ 编译并执行这个Executable ”。在这种情况下,我们需要将Executable(SQL表达式构造)与Connection对象或Engine对象(隐式获取Connection对象)进行显式绑定,以便execute()将知道在何处执行SQL

下面的示例很好地演示了它-给定如下表:

from sqlalchemy import MetaData, Table, Column, Integer

meta = MetaData()
users_table = Table('users', meta,
    Column('id', Integer, primary_key=True),
    Column('name', String(50)))

显式执行,Connection.execute()-将SQL文本或构造的SQL表达式传递给以下execute()方法Connection

engine = create_engine('sqlite:///file.db')
connection = engine.connect()
result = connection.execute(users_table.select())
for row in result:
    # ....
connection.close()

显式无连接执行,Engine.execute()-将SQL文本或构造的SQL表达式直接传递给execute()Engine方法:

engine = create_engine('sqlite:///file.db')
result = engine.execute(users_table.select())
for row in result:
    # ....
result.close()

隐式执行(Executable.execute()-)也是无连接的,并且调用的execute()方法Executable,即它execute()直接在SQL表达式构造(的实例Executable)本身上调用方法。

engine = create_engine('sqlite:///file.db')
meta.bind = engine
result = users_table.select().execute()
for row in result:
    # ....
result.close()

注意:出于说明的目的,陈述了隐式执行示例-强烈建议不按照这种方式执行这种执行方式-按照docs

“隐式执行”是一个非常古老的使用模式,在大多数情况下,它比有用的方法更令人困惑,并且不鼓励使用它。两种模式似乎都鼓励在应用程序设计中过度使用权宜之计的“捷径”,这会在以后导致问题。


你的问题:

据我了解,如果有人使用engine.execute,它将创建连接,打开会话(Alchemy会为您关心)并执行查询。

您认为“如果有人使用engine.execute它会创建connection” 这一部分是正确的,但对于“打开session(炼金术会为您关心)并执行查询”而言,您是正确的- 在形式上,使用Engine.execute()Connection.execute()(几乎)是同一件事,在形式上,Connection对象是隐式创建的,在以后的情况下,我们显式实例化它。在这种情况下真正发生的是:

`Engine` object (instantiated via `create_engine()`) -> `Connection` object (instantiated via `engine_instance.connect()`) -> `connection.execute({*SQL expression*})`

但是,执行此任务的这三种方式之间是否存在全局差异?

在数据库层,这完全是同一回事,所有这些都在执行SQL(文本表达式或各种SQL表达式构造)。从应用程序的角度来看,有两个选项:

  • 直接执行-使用Engine.execute()Connection.execute()
  • 使用sessions-通过有效地处理交易单单元的工作,轻松session.add()session.rollback()session.commit()session.close()。在ORM(即映射表)的情况下,这是与DB进行交互的方式。提供identity_map,以便在单个请求期间立即获取已被访问的对象或新创建/添加的对象。

Session.execute()最终使用Connection.execute()语句执行方法来执行SQL语句。使用Session对象是SQLAlchemy ORM建议的应用程序与数据库交互的方式。

文档摘录:

重要的是要注意,在使用SQLAlchemy ORM时,通常不访问这些对象。而是将Session对象用作数据库的接口。但是,对于围绕直接使用文本SQL语句和/或SQL表达式构造而无需ORM更高级别的管理服务参与的应用程序,“引擎”和“连接”为王(也是王后?),请继续阅读。

A one-line overview:

The behavior of execute() is same in all the cases, but they are 3 different methods, in Engine, Connection, and Session classes.

What exactly is execute():

To understand behavior of execute() we need to look into the Executable class. Executable is a superclass for all “statement” types of objects, including select(), delete(),update(), insert(), text() – in simplest words possible, an Executable is a SQL expression construct supported in SQLAlchemy.

In all the cases the execute() method takes the SQL text or constructed SQL expression i.e. any of the variety of SQL expression constructs supported in SQLAlchemy and returns query results (a ResultProxy – Wraps a DB-API cursor object to provide easier access to row columns.)


To clarify it further (only for conceptual clarification, not a recommended approach):

In addition to Engine.execute() (connectionless execution), Connection.execute(), and Session.execute(), it is also possible to use the execute() directly on any Executable construct. The Executable class has it’s own implementation of execute() – As per official documentation, one line description about what the execute() does is “Compile and execute this Executable“. In this case we need to explicitly bind the Executable (SQL expression construct) with a Connection object or, Engine object (which implicitly get a Connection object), so the execute() will know where to execute the SQL.

The following example demonstrates it well – Given a table as below:

from sqlalchemy import MetaData, Table, Column, Integer

meta = MetaData()
users_table = Table('users', meta,
    Column('id', Integer, primary_key=True),
    Column('name', String(50)))

Explicit execution i.e. Connection.execute() – passing the SQL text or constructed SQL expression to the execute() method of Connection:

engine = create_engine('sqlite:///file.db')
connection = engine.connect()
result = connection.execute(users_table.select())
for row in result:
    # ....
connection.close()

Explicit connectionless execution i.e. Engine.execute() – passing the SQL text or constructed SQL expression directly to the execute() method of Engine:

engine = create_engine('sqlite:///file.db')
result = engine.execute(users_table.select())
for row in result:
    # ....
result.close()

Implicit execution i.e. Executable.execute() – is also connectionless, and calls the execute() method of the Executable, that is, it calls execute() method directly on the SQL expression construct (an instance of Executable) itself.

engine = create_engine('sqlite:///file.db')
meta.bind = engine
result = users_table.select().execute()
for row in result:
    # ....
result.close()

Note: Stated the implicit execution example for the purpose of clarification – this way of execution is highly not recommended – as per docs:

“implicit execution” is a very old usage pattern that in most cases is more confusing than it is helpful, and its usage is discouraged. Both patterns seem to encourage the overuse of expedient “short cuts” in application design which lead to problems later on.


Your questions:

As I understand if someone use engine.execute it creates connection, opens session (Alchemy cares about it for you) and executes query.

You’re right for the part “if someone use engine.execute it creates connection ” but not for “opens session (Alchemy cares about it for you) and executes query ” – Using Engine.execute() and Connection.execute() is (almost) one the same thing, in formal, Connection object gets created implicitly, and in later case we explicitly instantiate it. What really happens in this case is:

`Engine` object (instantiated via `create_engine()`) -> `Connection` object (instantiated via `engine_instance.connect()`) -> `connection.execute({*SQL expression*})`

But is there a global difference between these three ways of performing such task?

At DB layer it’s exactly the same thing, all of them are executing SQL (text expression or various SQL expression constructs). From application’s point of view there are two options:

  • Direct execution – Using Engine.execute() or Connection.execute()
  • Using sessions – efficiently handles transaction as single unit-of-work, with ease via session.add(), session.rollback(), session.commit(), session.close(). It is the way to interact with the DB in case of ORM i.e. mapped tables. Provides identity_map for instantly getting already accessed or newly created/added objects during a single request.

Session.execute() ultimately uses Connection.execute() statement execution method in order to execute the SQL statement. Using Session object is SQLAlchemy ORM’s recommended way for an application to interact with the database.

An excerpt from the docs:

Its important to note that when using the SQLAlchemy ORM, these objects are not generally accessed; instead, the Session object is used as the interface to the database. However, for applications that are built around direct usage of textual SQL statements and/or SQL expression constructs without involvement by the ORM’s higher level management services, the Engine and Connection are king (and queen?) – read on.


回答 1

Nabeel的答案涵盖了很多细节并且很有帮助,但是我发现难以理解。由于这是该问题的第一个Google结果,因此,我对以后发现此问题的人们加深了理解:

运行.execute()

正如OP和Nabell Ahmed都指出的那样,执行平原时SELECT * FROM tablename,提供的结果没有区别。

这三个对象之间的区别取决于上下文就成为非常重要的SELECT声明中,或者更常见的是,当你想要做其他事情一样使用INSERTDELETE等等。

何时使用引擎,连接,会话

  • 引擎是SQLAlchemy使用的最低级别的对象。它维护了一个连接池,可在应用程序需要与数据库对话时使用。.execute()是一种先调用conn = engine.connect(close_with_result=True)然后调用的便捷方法conn.execute()。close_with_result参数表示连接自动关闭。(我稍微解释了源代码,但本质上是正确的)。编辑:这是engine.execute的源代码

    您可以使用引擎执行原始SQL。

    result = engine.execute('SELECT * FROM tablename;')
    #what engine.execute() is doing under the hood
    conn = engine.connect(close_with_result=True)
    result = conn.execute('SELECT * FROM tablename;')
    
    #after you iterate over the results, the result and connection get closed
    for row in result:
        print(result['columnname']
    
    #or you can explicitly close the result, which also closes the connection
    result.close()

    基本用法下的文档中对此进行了介绍。

  • 连接(正如我们在上面看到的)实际上是执行SQL查询的工作。每当您想更好地控制连接的属性,何时关闭连接等时,都应该执行此操作。例如,非常重要的示例是Transaction,它使您可以决定何时将更改提交到数据库。在正常使用中,更改是自动提交的。通过使用事务,您可以(例如)运行多个不同的SQL语句,如果其中一个出现问题,则可以立即撤消所有更改。

    connection = engine.connect()
    trans = connection.begin()
    try:
        connection.execute("INSERT INTO films VALUES ('Comedy', '82 minutes');")
        connection.execute("INSERT INTO datalog VALUES ('added a comedy');")
        trans.commit()
    except:
        trans.rollback()
        raise

    如果一次失败,这将使您撤消两项更改,就像您忘记创建数据日志表一样。

    因此,如果您正在执行原始SQL代码并需要控制,请使用连接

  • 会话用于SQLAlchemy的对象关系管理(ORM)方面(实际上,您可以从它们的导入方式中看到这一点:)from sqlalchemy.orm import sessionmaker。他们在后台使用连接和事务来运行其自动生成的SQL语句。.execute()是一个便捷功能,可传递到会话绑定的任何对象(通常是引擎,但可以是连接)。

    如果您使用的是ORM功能,请使用会话。如果只执行不绑定对象的直接SQL查询,则最好直接使用连接。

Nabeel’s answer covers a lot of details and is helpful, but I found it confusing to follow. Since this is currently the first Google result for this issue, adding my understanding of it for future people that find this question:

Running .execute()

As OP and Nabell Ahmed both note, when executing a plain SELECT * FROM tablename, there’s no difference in the result provided.

The differences between these three objects do become important depending on the context that the SELECT statement is used in or, more commonly, when you want to do other things like INSERT, DELETE, etc.

When to use Engine, Connection, Session generally

  • Engine is the lowest level object used by SQLAlchemy. It maintains a pool of connections available for use whenever the application needs to talk to the database. .execute() is a convenience method that first calls conn = engine.connect(close_with_result=True) and the then conn.execute(). The close_with_result parameter means the connection is closed automatically. (I’m slightly paraphrasing the source code, but essentially true). edit: Here’s the source code for engine.execute

    You can use engine to execute raw SQL.

    result = engine.execute('SELECT * FROM tablename;')
    #what engine.execute() is doing under the hood
    conn = engine.connect(close_with_result=True)
    result = conn.execute('SELECT * FROM tablename;')
    
    #after you iterate over the results, the result and connection get closed
    for row in result:
        print(result['columnname']
    
    #or you can explicitly close the result, which also closes the connection
    result.close()
    

    This is covered in the docs under basic usage.

  • Connection is (as we saw above) the thing that actually does the work of executing a SQL query. You should do this whenever you want greater control over attributes of the connection, when it gets closed, etc. For example, a very import example of this is a Transaction, which lets you decide when to commit your changes to the database. In normal use, changes are autocommitted. With the use of transactions, you could (for example) run several different SQL statements and if something goes wrong with one of them you could undo all the changes at once.

    connection = engine.connect()
    trans = connection.begin()
    try:
        connection.execute("INSERT INTO films VALUES ('Comedy', '82 minutes');")
        connection.execute("INSERT INTO datalog VALUES ('added a comedy');")
        trans.commit()
    except:
        trans.rollback()
        raise
    

    This would let you undo both changes if one failed, like if you forgot to create the datalog table.

    So if you’re executing raw SQL code and need control, use connections

  • Sessions are used for the Object Relationship Management (ORM) aspect of SQLAlchemy (in fact you can see this from how they’re imported: from sqlalchemy.orm import sessionmaker). They use connections and transactions under the hood to run their automatically-generated SQL statements. .execute() is a convenience function that passes through to whatever the session is bound to (usually an engine, but can be a connection).

    If you’re using the ORM functionality, use session; if you’re only doing straight SQL queries not bound to objects, you’re probably better off using connections directly.


回答 2

这是运行诸如GRANT之类的DCL(数据控制语言)的示例

def grantAccess(db, tb, user):
  import sqlalchemy as SA
  import psycopg2

  url = "{d}+{driver}://{u}:{p}@{h}:{port}/{db}".\
            format(d="redshift",
            driver='psycopg2',
            u=username,
            p=password,
            h=host,
            port=port,
            db=db)
  engine = SA.create_engine(url)
  cnn = engine.connect()
  trans = cnn.begin()
  strSQL = "GRANT SELECT on table " + tb + " to " + user + " ;"
  try:
      cnn.execute(strSQL)
      trans.commit()
  except:
      trans.rollback()
      raise

Here is an example of running DCL (Data Control Language) such as GRANT

def grantAccess(db, tb, user):
  import sqlalchemy as SA
  import psycopg2

  url = "{d}+{driver}://{u}:{p}@{h}:{port}/{db}".\
            format(d="redshift",
            driver='psycopg2',
            u=username,
            p=password,
            h=host,
            port=port,
            db=db)
  engine = SA.create_engine(url)
  cnn = engine.connect()
  trans = cnn.begin()
  strSQL = "GRANT SELECT on table " + tb + " to " + user + " ;"
  try:
      cnn.execute(strSQL)
      trans.commit()
  except:
      trans.rollback()
      raise

熊猫:索引数据框时出现多种情况-意外行为

问题:熊猫:索引数据框时出现多种情况-意外行为

我正在按两列中的值过滤数据框中的行。

出于某种原因,OR运算符的行为类似于我期望AND运算符的行为,反之亦然。

我的测试代码:

import pandas as pd

df = pd.DataFrame({'a': range(5), 'b': range(5) })

# let's insert some -1 values
df['a'][1] = -1
df['b'][1] = -1
df['a'][3] = -1
df['b'][4] = -1

df1 = df[(df.a != -1) & (df.b != -1)]
df2 = df[(df.a != -1) | (df.b != -1)]

print pd.concat([df, df1, df2], axis=1,
                keys = [ 'original df', 'using AND (&)', 'using OR (|)',])

结果:

      original df      using AND (&)      using OR (|)    
             a  b              a   b             a   b
0            0  0              0   0             0   0
1           -1 -1            NaN NaN           NaN NaN
2            2  2              2   2             2   2
3           -1  3            NaN NaN            -1   3
4            4 -1            NaN NaN             4  -1

[5 rows x 6 columns]

如您所见,AND运算符将删除其中至少一个等于的每一行-1。另一方面,OR运算符要求两个值相等-1才能删除它们。我期望结果恰好相反。任何人都可以解释这种行为吗?

我正在使用熊猫0.13.1。

I am filtering rows in a dataframe by values in two columns.

For some reason the OR operator behaves like I would expect AND operator to behave and vice versa.

My test code:

import pandas as pd

df = pd.DataFrame({'a': range(5), 'b': range(5) })

# let's insert some -1 values
df['a'][1] = -1
df['b'][1] = -1
df['a'][3] = -1
df['b'][4] = -1

df1 = df[(df.a != -1) & (df.b != -1)]
df2 = df[(df.a != -1) | (df.b != -1)]

print pd.concat([df, df1, df2], axis=1,
                keys = [ 'original df', 'using AND (&)', 'using OR (|)',])

And the result:

      original df      using AND (&)      using OR (|)    
             a  b              a   b             a   b
0            0  0              0   0             0   0
1           -1 -1            NaN NaN           NaN NaN
2            2  2              2   2             2   2
3           -1  3            NaN NaN            -1   3
4            4 -1            NaN NaN             4  -1

[5 rows x 6 columns]

As you can see, the AND operator drops every row in which at least one value equals -1. On the other hand, the OR operator requires both values to be equal to -1 to drop them. I would expect exactly the opposite result. Could anyone explain this behavior, please?

I am using pandas 0.13.1.


回答 0

如您所见,AND运算符会删除每一行中至少有一个等于-1的值。另一方面,OR运算符要求两个值都等于-1才能删除它们。

那就对了。请记住,您是根据要保留的内容而不是要丢弃的内容来写条件。对于df1

df1 = df[(df.a != -1) & (df.b != -1)]

您说的是“保留其中df.a不是-1且df.b不是-1的行”,这与删除其中至少一个值为-1的每一行相同。

对于df2

df2 = df[(df.a != -1) | (df.b != -1)]

您说的是“保留其中任一行df.adf.b都不为-1的行”,这与删除两个值均为-1的行相同。

PS:连锁访问会给df['a'][1] = -1您带来麻烦。最好养成使用.loc和的习惯.iloc

As you can see, the AND operator drops every row in which at least one value equals -1. On the other hand, the OR operator requires both values to be equal to -1 to drop them.

That’s right. Remember that you’re writing the condition in terms of what you want to keep, not in terms of what you want to drop. For df1:

df1 = df[(df.a != -1) & (df.b != -1)]

You’re saying “keep the rows in which df.a isn’t -1 and df.b isn’t -1″, which is the same as dropping every row in which at least one value is -1.

For df2:

df2 = df[(df.a != -1) | (df.b != -1)]

You’re saying “keep the rows in which either df.a or df.b is not -1″, which is the same as dropping rows where both values are -1.

PS: chained access like df['a'][1] = -1 can get you into trouble. It’s better to get into the habit of using .loc and .iloc.


回答 1

您可以使用query(),即:

df_filtered = df.query('a == 4 & b != 2')

You can use query(), i.e.:

df_filtered = df.query('a == 4 & b != 2')

回答 2

这里有一些数学逻辑理论

“ NOT a AND NOT b”“ NOT(a OR b)”相同,因此:

“ a NOT -1 AND b NOT -1” 等同于 “ NOT(a为-1 OR b为-1)”,与“(a is -1 OR b为-1)”的(补数)相反。

因此,如果您想要完全相反的结果,则df1和df2应如下所示:

df1 = df[(df.a != -1) & (df.b != -1)]
df2 = df[(df.a == -1) | (df.b == -1)]

A little mathematical logic theory here:

“NOT a AND NOT b” is the same as “NOT (a OR b)”, so:

“a NOT -1 AND b NOT -1” is equivalent of “NOT (a is -1 OR b is -1)”, which is opposite (Complement) of “(a is -1 OR b is -1)”.

So if you want exact opposite result, df1 and df2 should be as below:

df1 = df[(df.a != -1) & (df.b != -1)]
df2 = df[(df.a == -1) | (df.b == -1)]

在64位Windows上安装SetupTools

问题:在64位Windows上安装SetupTools

我在Windows 7 64位系统上运行Python 2.7,当我运行setuptools的安装程序时,它告诉我未安装Python 2.7。具体的错误消息是:

`Python Version 2.7 required which was not found in the registry`

我安装的Python版本是:

`Python 2.7 (r27:82525, Jul  4 2010, 07:43:08) [MSC v.1500 64 bit (AMD64)] on win32`

我正在看setuptools网站,它没有提到64位Windows的任何安装程序。我错过了什么吗,还是必须从源代码安装它?

I’m running Python 2.7 on Windows 7 64-bit, and when I run the installer for setuptools it tells me that Python 2.7 is not installed. The specific error message is:

`Python Version 2.7 required which was not found in the registry`

My installed version of Python is:

`Python 2.7 (r27:82525, Jul  4 2010, 07:43:08) [MSC v.1500 64 bit (AMD64)] on win32`

I’m looking at the setuptools site and it doesn’t mention any installers for 64-bit Windows. Have I missed something or do I have to install this from source?


回答 0

显然(在OS X上面临相关的64位和32位问题),Windows安装程序中存在一个错误。我偶然发现了这种解决方法,它可能会有所帮助-基本上,您可以创建自己的注册表值,HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Python\PythonCore\2.6\InstallPath然后从中复制InstallPath值HKEY_LOCAL_MACHINE\SOFTWARE\Python\PythonCore\2.6\InstallPath。有关更多详细信息,请参见下面的答案。

如果执行此操作,请注意setuptools 只能安装32位库

注意:以下回复提供了更多详细信息,因此也请阅读它们。

Apparently (having faced related 64- and 32-bit issues on OS X) there is a bug in the Windows installer. I stumbled across this workaround, which might help – basically, you create your own registry value HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Python\PythonCore\2.6\InstallPath and copy over the InstallPath value from HKEY_LOCAL_MACHINE\SOFTWARE\Python\PythonCore\2.6\InstallPath. See the answer below for more details.

If you do this, beware that setuptools may only install 32-bit libraries.

NOTE: the responses below offer more detail, so please read them too.


回答 1

问题:您有64位Python和32位安装程序。这将导致扩展模块出现问题。

安装程序找不到Python的原因是Windows 7提供的透明32位仿真。64位和32位程序将写入Windows注册表的不同部分。

64位: HKLM|HKCU\SOFTWARE\

32位:HKLM|HKCU\SOFTWARE\wow6432node\

这意味着64位Python安装程序会写入HKLM\SOFTWARE\Python,而32位setuptools安装程序会查看HKLM\SOFTWARE\wow6432node\Python(这是由Windows自动处理的,程序不会注意到)。这是预期的行为,而不是错误。

通常,您有以下选择:

  • “干净”的方式:如果必须使用32位模块或扩展,请使用32位Python
  • 另一种“干净”的方式:仅在使用64位Python时才使用64位安装程序(请参见下文)
  • 上面的答案表明了什么:复制HKLM\SOFTWARE\PythonHKLM\SOFTWARE\wow6432node\Python,但这导致二进制分发出现问题,因为64位Python无法加载32位编译模块(请勿这样做!)
  • 使用setuptools而不是distutils安装程序(easy_install或pip)安装纯Python模块

例如,对于setuptools本身,您不能将32位安装程序用于64位Python,因为它包含二进制文件。但是在http://www.lfd.uci.edu/~gohlke/pythonlibs/中有一个64位安装程序(其他模块也有许多安装程序)。如今,PyPi上的许多软件包都有二进制发行版,因此您可以通过pip安装它们。

Problem: you have 64-bit Python, and a 32-bit installer. This will cause problems for extension modules.

The reasons why the installer doesn’t finds Python is the transparent 32-bit emulation from Windows 7. 64-bit and 32-bit programs will write to different parts of the Windows registry.

64-bit: HKLM|HKCU\SOFTWARE\

32-bit: HKLM|HKCU\SOFTWARE\wow6432node\.

This means that the 64-bit Python installer writes to HKLM\SOFTWARE\Python, but the 32-bit setuptools installer looks at HKLM\SOFTWARE\wow6432node\Python (this is handled by windows automatically, programs don’t notice). This is expected behavior and not a bug.

Usually, you have these choices:

  • the “clean” way: use 32-bit Python if you have to use 32-bit modules or extensions
  • the other “clean” way: only use 64-bit installers when using 64-bit Python (see below)
  • what the answer above suggests: copy HKLM\SOFTWARE\Python to HKLM\SOFTWARE\wow6432node\Python, but this will cause problems with binary distributions, as 64-bit Python can’t load 32-bit compiled modules (do NOT do this!)
  • install pure Python modules with setuptools instead of the distutils installer (easy_install or pip)

For setuptools itself, for example, you can’t use a 32-bit installer for 64-bit Python as it includes binary files. But there’s a 64-bit installer at http://www.lfd.uci.edu/~gohlke/pythonlibs/ (has many installers for other modules too). Nowadays, many packages on PyPi have binary distributions, so you can install them via pip.


回答 2

我做了一个注册表(.reg)文件,它将自动为您更改注册表。如果安装在“ C:\ Python27”中,它将起作用:

下载32位版本 HKEY_LOCAL_MACHINE|HKEY_CURRENT_USER\SOFTWARE\wow6432node\

下载64位版本 HKEY_LOCAL_MACHINE|HKEY_CURRENT_USER\SOFTWARE\

I made a registry (.reg) file that will automatically change the registry for you. It works if it’s installed in “C:\Python27”:

Download 32-bit version HKEY_LOCAL_MACHINE|HKEY_CURRENT_USER\SOFTWARE\wow6432node\

Download 64-bit version HKEY_LOCAL_MACHINE|HKEY_CURRENT_USER\SOFTWARE\


回答 3

是的,您是对的,问题出在setuptools的64位Python和32位安装程序上。

在Windows上安装64位setuptools的最佳方法是将ez_setup.py下载到C:\ Python27 \ Scripts并运行它。它将下载用于setuptools的适当的64位.egg文件并为您安装。

资料来源:http : //pypi.python.org/pypi/setuptools

PS我建议您不要使用第三方的64位.exe setuptools安装程序或操纵注册表

Yes, you are correct, the issue is with 64-bit Python and 32-bit installer for setuptools.

The best way to get 64-bit setuptools installed on Windows is to download ez_setup.py to C:\Python27\Scripts and run it. It will download appropriate 64-bit .egg file for setuptools and install it for you.

Source: http://pypi.python.org/pypi/setuptools

P.S. I’d recommend against using 3rd party 64-bit .exe setuptools installers or manipulating registry


回答 4

创建一个名为python2.7.reg(注册表文件)的文件,并将其内容放入其中:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Python\PythonCore\2.7]

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Python\PythonCore\2.7\Help]

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Python\PythonCore\2.7\Help\MainPythonDocumentation]
@="C:\\Python27\\Doc\\python26.chm"

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Python\PythonCore\2.7\InstallPath]
@="C:\\Python27\\"

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Python\PythonCore\2.7\InstallPath\InstallGroup]
@="Python 2.7"

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Python\PythonCore\2.7\Modules]

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Python\PythonCore\2.7\PythonPath]
@="C:\\Python27\\Lib;C:\\Python27\\DLLs;C:\\Python27\\Lib\\lib-tk"

并确保每条路径都是正确的!

然后运行(合并)并完成:)

Create a file named python2.7.reg (registry file) and put this content into it:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Python\PythonCore\2.7]

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Python\PythonCore\2.7\Help]

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Python\PythonCore\2.7\Help\MainPythonDocumentation]
@="C:\\Python27\\Doc\\python26.chm"

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Python\PythonCore\2.7\InstallPath]
@="C:\\Python27\\"

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Python\PythonCore\2.7\InstallPath\InstallGroup]
@="Python 2.7"

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Python\PythonCore\2.7\Modules]

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Python\PythonCore\2.7\PythonPath]
@="C:\\Python27\\Lib;C:\\Python27\\DLLs;C:\\Python27\\Lib\\lib-tk"

And make sure every path is right!

Then run (merge) it and done :)


回答 5

register.py这个要点获取文件。将其保存在您的C驱动器或D驱动器上,转到CMD以运行它:

'python register.py'

然后,您将能够安装它。

Get the file register.py from this gist. Save it on your C drive or D drive, go to CMD to run it with:

'python register.py'

Then you will be able to install it.


回答 6

对于Windows上的64位Python,请下载ez_setup.py并运行它;它将下载适当的.egg文件并为您安装。

由于distutils安装程序兼容性问题,在撰写本文时,.exe安装程序不支持Windows的64位版本的Python 。

For 64-bit Python on Windows download ez_setup.py and run it; it will download the appropriate .egg file and install it for you.

At the time of writing the .exe installer does not support 64-bit versions of Python for Windows, due to a distutils installer compatibility issue.


回答 7

要允许Windows安装程序在Windows 7Windows 7中找到已安装的Python目录,请更改要将安装程序安装到的Python安装,然后将已安装的路径添加到InstallPath注册表项的(默认)值中:

HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \ Python \ PythonCore \ 2.X \ InstallPath

其中“ X ”是Python版本(即2.5、2.6或2.7)。

To allow Windows installers to find the installed Python directory in Windows 7, OR, change which Python installation to install an installer into, add the installed path into the InstallPath registry key’s (Default) value:

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Python\PythonCore\2.X\InstallPath

Where “X” is the Python version (that is, 2.5, 2.6, or 2.7).


回答 8

我尝试了上述操作,但将注册表项添加到LOCALMACHINE并没有完成任务。因此,如果您仍然被卡住,请尝试此操作。

Windows注册表编辑器版本5.00

[HKEY_CURRENT_USER \ SOFTWARE \ Python]

[HKEY_CURRENT_USER \ SOFTWARE \ Python \ PythonCore]

[HKEY_CURRENT_USER \ SOFTWARE \ Python \ PythonCore \ 2.7]

[HKEY_CURRENT_USER \ SOFTWARE \ Python \ PythonCore \ 2.7 \ Help]

[HKEY_CURRENT_USER \ SOFTWARE \ Python \ PythonCore \ 2.7 \ Help \ Main Python文档] @ =“ C:\ Python27 \ Doc \ python272.chm”

[HKEY_CURRENT_USER \ SOFTWARE \ Python \ PythonCore \ 2.7 \ InstallPath] @ =“ C:\ Python27 \”

[HKEY_CURRENT_USER \ SOFTWARE \ Python \ PythonCore \ 2.7 \ InstallPath \ InstallGroup] @ =“ Python 2.7”

[HKEY_CURRENT_USER \ SOFTWARE \ Python \ PythonCore \ 2.7 \ Modules]

[HKEY_CURRENT_USER \ SOFTWARE \ Python \ PythonCore \ 2.7 \ PythonPath] @ =“ C:\ Python27 \ Lib; C:\ Python27 \ DLLs; C:\ Python27 \ Lib \ lib-tk”

将以上内容复制粘贴到记事本中,并将其另存为Python27.reg。现在,按照上述答案中的说明运行/合并文件。(请确保根据您的安装更正了Python安装路径。

上面的答案对本地用户的建议对当前用户来说确实很简单。

I tried the above and adding the registry keys to the LOCALMACHINE was not getting the job done. So in case you are still stuck , try this.

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\SOFTWARE\Python]

[HKEY_CURRENT_USER\SOFTWARE\Python\PythonCore]

[HKEY_CURRENT_USER\SOFTWARE\Python\PythonCore\2.7]

[HKEY_CURRENT_USER\SOFTWARE\Python\PythonCore\2.7\Help]

[HKEY_CURRENT_USER\SOFTWARE\Python\PythonCore\2.7\Help\Main Python Documentation] @=”C:\Python27\Doc\python272.chm”

[HKEY_CURRENT_USER\SOFTWARE\Python\PythonCore\2.7\InstallPath] @=”C:\Python27\”

[HKEY_CURRENT_USER\SOFTWARE\Python\PythonCore\2.7\InstallPath\InstallGroup] @=”Python 2.7″

[HKEY_CURRENT_USER\SOFTWARE\Python\PythonCore\2.7\Modules]

[HKEY_CURRENT_USER\SOFTWARE\Python\PythonCore\2.7\PythonPath] @=”C:\Python27\Lib;C:\Python27\DLLs;C:\Python27\Lib\lib-tk”

Copy paste the above in notepad and save it as Python27.reg . Now run/merge the file as mentioned in the answers above. (Make sure the paths of Python installation are corrected as per your installation.

It simply does ,what the above answers suggest for a local machine ,to the current user.


回答 9

这是另一个帖子/主题的链接。我能够运行此脚本来自动注册python 2.7。(确保从.exe要注册的Python 2.x运行它!)

要注册Python 3.x,我必须修改print语法并导入winreg(而不是_winreg),然后运行Python 3 .exe

https://stackoverflow.com/a/29633714/3568893

Here is a link to another post/thread. I was able run this script to automate registration of Python 2.7. (Make sure to run it from the Python 2.x .exe you want to register!)

To register Python 3.x I had to modify the print syntax and import winreg (instead of _winreg), then run the Python 3 .exe.

https://stackoverflow.com/a/29633714/3568893


回答 10

您可以在此处找到许多库的64位安装程序:http : //www.lfd.uci.edu/~gohlke/pythonlibs/

You can find 64bit installers for a lot of libs here: http://www.lfd.uci.edu/~gohlke/pythonlibs/


对python 2.7的支持终止了吗?

问题:对python 2.7的支持终止了吗?

当不再支持python 2.7而不再支持python 2.7时,是否存在已知的日期/时间框架?

Is there a known date/timeframe when python 2.7 will not be supported any more in favor of python 3?


回答 0

自2014年4月13日起,来自http://hg.python.org/peps/rev/76d43e52d978(PEP 373,Python 2.7发布时间表):

Python 2.7的终止生命日期(停产日期,终止日期)已移至未来五年,即2020年。此决定旨在阐明Python 2.7的状态,并减轻那些尚无法迁移到Python 3的用户的后顾之忧。另请参阅PEP 466

As of 13 Apr 2014, from http://hg.python.org/peps/rev/76d43e52d978 (PEP 373, Python 2.7 Release Schedule):

The End Of Life date (EOL, sunset date) for Python 2.7 has been moved five years into the future, to 2020. This decision was made to clarify the status of Python 2.7 and relieve worries for those users who cannot yet migrate to Python 3. See also PEP 466.


回答 1

2010年5月,神的话语为Python 2.7 PATCHLEVEL版本将可能至少6年内作出

因此,也许是2016年,也许是以后。

编辑:推回2020年。请参阅PEP 373的修订版,并在其他答案中链接。

In May 2010, Word of God was that patchlevel releases for Python 2.7 will probably be made for at least 6 years.

So, maybe 2016, probably later.

Edit: Pushed back to 2020. See the revision to PEP 373, linked to in other answers.


回答 2

最近,该日期已更新为2020年1月1日。

参见https://pythonclock.org/

Recently, that date has been updated to January 1, 2020.

see https://pythonclock.org/


回答 3

您应该仔细阅读以下内容(参考:https : //news.ycombinator.com/item ? id =7582300):

这里没有来自python-dev列表的人有很多评论,他们并不真正理解这种差异的实际含义。核心开发人员无需维持2015年后的2.7,并且大多数人不会参与其中。那部分没有改变。发生的事情是Red Hat准备削减RHEL 7发行版,AFAIK取决于您为他们支付13年支持的费用。因此,他们将需要弄清楚如何至少在2027年之前自己获得2.7的支持。RH完全有权利分叉Python,并为自己和客户保留维护补丁(Python不是copyleft)。但,他们是好人,因此,如果仍有Python项目愿意接受这些更改,也许他们愿意至少暂时进行更改。再次,这是我基于ML讨论的推测,而不是RH实​​际上说过的。可以比喻Rails LTS,它是patio11参与[0]的Rails 2.x的商业分支。不可避免地会有人介入以支持2.7,所以让我们看看如何避免出现这样的情况,即保持2.7唯一运行的唯一方法是订阅RHEL。同时,有一些大公司在Windows上广泛使用2.7(例如Enthought,Anaconda),并且认为可以找到某个人偶尔制作Windows安装程序,前提是假定Python.org仍将托管下载。因此,实际上发生的事情不是很令人兴奋。核心提交者所做的工作与将项目按原计划进行一样没有什么不同。发生的情况是,它们将使源代码控制存储库和FTP服务器中的指示灯保持打开状态,以便捕获有兴趣继续支持2.7的大公司员工的免费劳动力。另一种选择是,RH和其他供应商创建专有且昂贵的Python 2.7分支。无论如何,这种情况最终可能会发生,但是如果二进制文件仍然出现在python.org上,并且您不必要求IT部门设置SCM和错误跟踪器,那么雇主将需要更长的时间才能注意到您应该停止提供补丁。等等 发生的情况是,它们将使源代码控制存储库和FTP服务器中的指示灯保持打开状态,以便捕获有兴趣继续支持2.7的大公司员工的免费劳动力。另一种选择是,RH和其他供应商创建专有且昂贵的Python 2.7分支。无论如何,这种情况最终可能会发生,但是如果二进制文件仍然出现在python.org上,并且您不必要求IT部门设置SCM和错误跟踪器,那么雇主将需要更长的时间才能注意到您应该停止提供补丁。等等 发生的情况是,它们将使源代码控制存储库和FTP服务器中的指示灯保持打开状态,以便捕获有兴趣继续支持2.7的大公司员工的免费劳动力。另一种选择是,RH和其他供应商创建专有且昂贵的Python 2.7分支。无论如何,这种情况最终可能会发生,但是如果二进制文件仍然出现在python.org上,并且您不必要求IT部门设置SCM和错误跟踪器,那么雇主将需要更长的时间才能注意到您应该停止提供补丁。等等

you should read this carefully (ref : https://news.ycombinator.com/item?id=7582300 ):

There are a lot of comments here from people who aren’t on the python-dev list and don’t really understand what this diff actually means. The core developers are not required to maintain 2.7 post-2015, and most of them won’t be involved in it. That part hasn’t changed. What is happening is that Red Hat is preparing to cut a RHEL 7 release, which AFAIK depending on how much you pay them they support for 13 years. So they will need to figure out how to support 2.7 themselves at least through 2027. Here is where I am reading between the lines. RH are well within their right to fork Python and keep their maintenance patches to themselves and their customers (Python’s not copyleft). But, they are nice guys and so maybe they are willing to upstream their changes at least for awhile if there is still a Python project willing to accept them. Again, this is my speculation based on the ML discussion, not what RH has actually said they will do. An analogy can be made to Rails LTS, a commercial fork of Rails 2.x that patio11 was involved in [0]. Inevitably somebody is going to step in to support 2.7, and so let’s see what we can do to avoid a situation where the only way to keep running 2.7 is to subscribe to RHEL. Meanwhile, there are some large companies that use 2.7 extensively on Windows (e.g. Enthought, Anaconda) and the thinking goes that somebody can probably be found to produce a Windows installer once in awhile, assuming that Python.org will still host a download. So really what is happening here is not very exciting. The core committers aren’t doing anything different than leaving the project as originally planned. What is happening is that they will leave the lights on in the source control repository and on the FTP server, so as to capture the free labor from people at large companies who have an interest in continuing to support 2.7. The alternative is that RH and other vendors create proprietary and expensive forks of Python 2.7. That may end up happening anyway, but it will take longer for your employer to notice you should stop contributing your patches back if binaries still appear on python.org and you don’t have to ask IT to set up SCM and a bug tracker, etc.


回答 4

本文说:“当2.7发布时,2.x系列将进入五年的仅漏洞修复模式。”

因此,据我所知,Python 2.7是最后一个添加2.x功能的版本,尽管发现的错误将被修复(一段时间),但新功能仅适用于3.x版本。

This article says: “When 2.7 is released, the 2.x line will move into five years of a bug fix-only mode.”

So, as far as I see, Python 2.7 was the last 2.x feature-adding release, and though found bugs are going to be fixed (for some time), new features only go to 3.x releases.


回答 5

到2020年EOS 倒计时还不错。

There is also a pretty ominous countdown clock to the EOS at 2020.


回答 6

PEP 373(Python 2.7发布时间表)是您要求的那种信息的正式来源。

当前显示“计划的未来发布日期:”

  • 2014年5月2.7.7
  • 2.7.8 2014年11月
  • 2015年5月2.7.9
  • 在此日期之后,根据需要发布

另外,它说:“ Python 2.7的生命终止日期(停产日期,日落日期)已经移到了五年后的2020年。”

根据http://hg.python.org/peps/rev/76d43e52d978在2014年4月编辑

PEP 373 (Python 2.7 Release Schedule) is the official source for the kind of information you asked for.

It currently says “Planned future release dates:”

  • 2.7.7 May 2014
  • 2.7.8 November 2014
  • 2.7.9 May 2015
  • beyond this date, releases as needed

Also, it says “The End Of Life date (EOL, sunset date) for Python 2.7 has been moved five years into the future, to 2020.”

Edited in April 2014, according to http://hg.python.org/peps/rev/76d43e52d978


回答 7

《 Python开发人员指南》列出了从2.6版到当前版本的“ Python分支的状态 ”,包括其当前支持状态以及生命周期终止日期。

当前受支持(错误+安全修复):

  • Python 3.8(当前的master / develop分支)
  • Python 3.7
  • Python 3.6
  • Python 2.7(直到2020-01-01)

仅安全修复程序:

  • Python 3.5
  • Python 3.4

The Python Developer’s Guide lists the “Status of Python branches” from version 2.6 up to the current version, including their current support status with End-of-life dates.

Currently supported (bug + security fixes):

  • Python 3.8 (current master/development branch)
  • Python 3.7
  • Python 3.6
  • Python 2.7 (until 2020-01-01)

Security fixes only:

  • Python 3.5
  • Python 3.4

回答 8

Python 2.7将会永远存在。有太多使用它的旧代码,没有人愿意重写。已经有一个名为Tauthon的分支,但是如果这个毫无意义的截止日期成为现实,我们可能还会看到其他人。

Python 2.7 wil be around forever. There is too much old code that uses it that no one wants to rewrite. There is already a fork called Tauthon, but we may see others if this pointless deadline gets real.


用python练习BDD [关闭]

问题:用python练习BDD [关闭]

python有哪些最先进的框架和工具可用于实践行为驱动开发?尤其是找到与rspec和mocha类似的工具来进行红宝石搜索将是很棒的。

Which are the most advanced frameworks and tools there are available for python for practicing Behavior Driven Development? Especially finding similar tools as rspec and mocha for ruby would be great.


回答 0

Ian Bicking建议将doctest用于行为驱动的设计:

我个人倾向于以行为驱动的设计风格使用鼻子空隙模拟。具体来说,鼻子的规范插件非常适合BDD。

Ian Bicking recommends using doctest for behavior driven design:

I personally tend to use nose and voidspace mock in a behavior driven design style. Specifically, the spec plugin for nose is excellent for BDD.


回答 1

生菜意味着要成为类似python的黄瓜类工具:http//lettuce.it/

您可以在github.com/gabrielfalcao/lettuce上获取源代码

Lettuce means to be a cucumber-like tool for python: http://lettuce.it/

You can grab the source at github.com/gabrielfalcao/lettuce


回答 2

我真的建议您表现良好

在寻找适用于Python的黄瓜克隆时,我开始使用生菜,但发现它是一个笨拙设计的副本。非常不合常规。

然后我发现了行为,并对此感到非常满意。

I really recommend behave.

Looking for a Cucumber clone for Python, I started using lettuce, but found it a pretty clumsily designed replica. Very Unpythonic.

Then I discovered behave, and have been really happy with it.


回答 3

我建议您使用开发的一组工具来帮助程序员进行BDD和TDD的实践。该工具集由pycukesspecloudludibrioshould-dsl组成

Should-DSL将给您类似RSpec的期望。您可以使用RSpec期望API进行的所有操作,should-dsl也可以。您可以从Github获取最新版本

SpecLoud帮助您进行类似BDD的单元测试。您可以通过执行安装

pip install specloud

Ludibrio是一个用于测试双打(假人,存根和假人)的库。通过安装

pip install ludibrio

PyCukes是BDD的主要工具。它将运行场景,等等。再次,

pip install pycukes

有关更多信息,请阅读PyPi上的工具文档。

I recommend you to use a set of tools developed to help programmers in the practice of BDD and TDD. This tool set is composed by: pycukes, specloud, ludibrio and should-dsl.

Should-DSL will give you RSpec-like expectations. Everything you can do with RSpec expectation API, should-dsl does too. You can grab the latestversion from Github.

SpecLoud helps you on running BDD-like unittests. You can install it by doing

pip install specloud

Ludibrio is a library for test doubles (Mocks, Stubs and Dummies). Install it via

pip install ludibrio

And PyCukes is the main tool for BDD. It will run the Scenarios, etc. Again,

pip install pycukes

For more info please read the tools documentation at PyPi.


回答 4

很棒的帖子和答案。只是想更新包括梳洗在此列表中,因为我读pycukes被中断。有关使用BDD和Django的与梳洗好后是在这里

Great post and answers. Just wanted to update to include Freshen in this list as I read pycukes is discontinued. A good post about using BDD and Django with Freshen is here.


回答 5

您可以将“ sure”用于表达性断言(就像在RSpec中一样)

You can use “sure” for expressive assertions (just like in RSpec)


回答 6

Pyccuracy项目致力于为Python中的BDD提供特定领域的语言。

与在API级别上工作的doctest不同,它对更高级别的操作进行编码,例如加载网页和提交表单。我没有使用过它,但是如果您正在寻找它,它看起来很有希望。

The Pyccuracy project is an effort to provide a domain-specific language for BDD in Python.

Unlike doctest, which works at the API level, it encodes higher-level operations such as loading a web page and submitting a form. I haven’t used it but it looks somewhat promising if that is what you’re looking for.


回答 7

我非常喜欢Pyccuracy。这些天,我正在一个中型项目中实现它。

I like Pyccuracy a lot. I’m implementing it on a mid sized project these days.


回答 8

试用pyspecs。使测试易于阅读并在开发过程中持续运行是我创建此项目的两个主要目标。

测试代码:

from pyspecs import given, when, then, and_, the, this

with given.two_operands:
    a = 2
    b = 3

    with when.supplied_to_the_add_function:
        total = a + b

        with then.the_total_should_be_mathmatically_correct:
            the(total).should.equal(5)

        with and_.the_total_should_be_greater_than_either_operand:
            the(total).should.be_greater_than(a)
            the(total).should.be_greater_than(b)

    with when.supplied_to_the_subtract_function:
        difference = b - a

        with then.the_difference_should_be_mathmatically_correct:
            the(difference).should.equal(1)

控制台输出:

# run_pyspecs.py

  |  given two operands 
  |    when supplied to the add function 
  |      then the total should be mathmatically correct 
  |      and the total should be greater than either operand 
  |    when supplied to the subtract function 
  |      then the difference should be mathmatically correct 

(ok) 6 passed (6 steps, 1 scenarios in 0.0002 seconds)

Try out pyspecs. Making tests easy to read and constantly running during development were two of my main goals in creating this project.

Test Code:

from pyspecs import given, when, then, and_, the, this

with given.two_operands:
    a = 2
    b = 3

    with when.supplied_to_the_add_function:
        total = a + b

        with then.the_total_should_be_mathmatically_correct:
            the(total).should.equal(5)

        with and_.the_total_should_be_greater_than_either_operand:
            the(total).should.be_greater_than(a)
            the(total).should.be_greater_than(b)

    with when.supplied_to_the_subtract_function:
        difference = b - a

        with then.the_difference_should_be_mathmatically_correct:
            the(difference).should.equal(1)

Console Output:

# run_pyspecs.py

  | • given two operands 
  |   • when supplied to the add function 
  |     • then the total should be mathmatically correct 
  |     • and the total should be greater than either operand 
  |   • when supplied to the subtract function 
  |     • then the difference should be mathmatically correct 

(ok) 6 passed (6 steps, 1 scenarios in 0.0002 seconds)

回答 9

我可能完全忘记了这一点,但是我保留的原始BDD论文是BDD只是重新包装了TDD,以强调一些最佳实践。

如果我的解释是正确的,则只需在任何xUnit实现中重命名方法即可获得BDD框架。因此,只需继续使用标准库的unittest即可

编辑:一个快速的谷歌在奶酪店里出现了一个行为模块。进一步搜索 BDD那里没有找到其他任何东西。

I am probably completely missing the point, but what I retained of the original BDD paper was that BDD was just TDD repackaged to emphasize some best practices.

If my interpretation is correct, you can get a BDD framework just by renaming methods around in any xUnit implementation. So just go ahead and use the standard library’s unittest.

EDIT: A quick google turned up a Behaviour module in the Cheese Shop. Further searching for BDD there did not find anything else.


在Mac OS X上,适用于Python的IDE是什么?[关闭]

问题:在Mac OS X上,适用于Python的IDE是什么?[关闭]

我将开始一项新工作,其中的编码实践主要围绕TDD和重构进行,并且其主要开发语言是Python。我来自Java世界,长期以来一直是Eclipse的自信用户。不使用Java时,我使用emacs。

我正在寻找一个适用于Python的IDE,该IDE将提供与Eclipse一起使用的许多功能,不仅用于重构,而且还涉及代码完成,项目管理,SCM集成(当前为CVS,但可能这些天之一切换到git)等。

我应该使用哪种IDE?

I’m about to start a new job where the coding practices are heavily centered around TDD and refactoring, and whose primary development language is Python. I come from the Java world, and have been a confident user of Eclipse for a good, long time. When not working in Java, I use emacs.

I’m looking for an IDE for Python that will give me a lot of the capabilities I’ve grown used to with Eclipse, not only for refactoring but in terms of code completion, project management, SCM integration (currently CVS, but likely to switch to git one of these days) et al.

What IDE should I use?


回答 0

尝试了许多不同的方法(Kate,Eclipse,Scite,Vim,Komodo):每个函数都有一些故障,要么功能有限,要么反应缓慢且反应迟钝。多年后的最终选择:Emacs + ropemas + flymake。绳索项目文件打开对话框非常快捷。绳索重构和代码辅助功能非常有用。Flymake显示语法错误。Emacs是最可配置的编辑器。我对此配置感到非常满意。配置的Python相关部分位于此处:public.halogen-dg.com浏览器/alex-emacs-settings/configs/cfg_python.el

Have tried many different (Kate, Eclipse, Scite, Vim, Komodo): each one have some glitches, either limited functions, or slow and unresponsive. Final choice after many years: Emacs + ropemacs + flymake. Rope project file open dialog is extremely quick. Rope refactoring and code assist functions are super helpful. Flymake shows syntax mistakes. Emacs is the most configurable editor. I am very happy with this config. Python related part of config is here: public.halogen-dg.com browser/alex-emacs-settings/configs/cfg_python.el


回答 1

我的2便士,请查看PyCharm http://www.jetbrains.com/pycharm/

(也是多平台的)

My 2 pennies, check out PyCharm http://www.jetbrains.com/pycharm/

(also multi-platform)


回答 2

我将TextMate用于我的所有Python编程需求。它本身并不是一个IDE,但是它可以做很多IDE可以做的事情(没有IDE的全部麻烦)。它具有语法突出显示,代码折叠,通过使用其他捆绑软件与各种SCM集成(我知道它支持SVN,Git,Mercurial,Darcs以及其他一些支持)。它也具有相当的可扩展性和可定制性(再次通过使用包)。它还具有项目的基本概念。但是,它不发光的一个地方是代码完成。一些捆绑软件对代码完成的支持有限,但是通常不像大多数特定语言的IDE那样令人惊奇。但是,鉴于TextMate的出色表现,我不知道要牺牲多少。TextMate绝对使我的工作效率更高。

I use TextMate for all my Python programming needs. It’s not an IDE per se, but it does a lot of stuff that an IDE does (without all the cruft of an IDE). It has syntax highlighting, code folding, integration with various SCMs through the use of additional bundles (I know it supports SVN, Git, Mercurial, Darcs, and probably a few others). It’s also quite extensible and customizable (again, through the use of bundles). It also has a basic concept of projects. One place where it doesn’t shine, though, is in code completion; some bundles have limited support for code completion, but it’s generally not as amazing as that of most language-specific IDEs. Given how awesome TextMate is, though, I don’t know sacrificing that. TextMate’s definitely made me much more productive.


回答 3

正如其他人所提到的,用于Eclipse的Pydev很好。

Netbeans有一个Beta版Python插件,边缘有些粗糙,但可能会变得很酷。

此外,有很多针对Mac的以编程为中心的文本编辑器,它们可能满足或不满足您的需求。

  • Textmate-花钱,人们喜欢这个程序,但是我还没有足够用它来了解所有的大惊小怪。
  • Jedit-基于Java的文本编辑器,具有一些不错的功能,但是启动时间并不好(由于Java)。
  • CarbonEmacs-体面的Emacs端口。
  • AquaEmacs-更好的Emacs端口。
  • TextWrangler -Lite,BBEdit的免费版本(如啤酒)。
  • BBEdit-老兵。Textmate之前的事实编辑偷走了风头。昂贵。
  • Smultron-非常好的编辑器,UI类似于Textmate。
  • 空闲 -Python自己的小编辑器,具有一些不错的功能,但也存在一些主要问题。我个人觉得使用起来太不稳定了。
  • Sublime TextSublime文本) -这是一个非常好的文本编辑器,具有令人惊讶的良好Python支持。
  • Pycharm-用于Python的IDE上的另一个完整版本。

Pydev for Eclipse, as others have mentioned, is good.

Netbeans has a beta Python plugin that is a little rough around the edges, but could turn into something really cool.

Additionally there is a long list of programming centric text editors for the mac, that may or may not fit your needs.

  • Textmate – costs money, people love this program, but I haven’t used it enough to see what all the fuss is about.
  • Jedit – Java based text editor, has some nice features, but the startup time isn’t great (due to Java).
  • CarbonEmacs – Decent Emacs port.
  • AquaEmacs – Better Emacs port.
  • TextWrangler – Lite, free (as in beer) verision of BBEdit.
  • BBEdit – The old guard. The defacto editor before Textmate stole its limelight. Expensive.
  • Smultron – Very nice editor, the UI is similar to Textmate.
  • Idle – Python’s own little editor, has some nice features, but also some major problems. I’ve personally found it too unstable for my usage.
  • Sublime Text – This is really sweet text editor that has some surprisingly good Python support.
  • Pycharm – Another solid full on IDE for Python.

回答 4

带有Pydev的 Eclipse 在任何平台上最适合我。

Eclipse with Pydev works best for me on any platform.


回答 5

我真的很喜欢使用PyCharm。http://www.jetbrains.com/pycharm/


回答 6

我通常将komodo editaquamacsropemas 一起使用。尽管我应该警告您,但是如果您来自Java或C#背景,IDE功能将不再是您惯用的功能。我个人发现,功能强大的IDE会比他们提供的帮助更多。

更新:我还应该指出,如果您有钱,Komodo IDE是值得的。这是Komodo Edit的付费版本。

I usually use either komodo edit or aquamacs with ropemacs. Although I should warn you, IDE features won’t be what you’re used to if you’re coming from a Java or C# background. I personally find that powerful IDEs get in my way more than they help.

UPDATE: I should also point out that if you have the money Komodo IDE is worth it. It’s the paid version of Komodo Edit.


回答 7

macvim + pyflakes.vim

macvim + pyflakes.vim


回答 8

我喜欢Spyder,它具有许多工具,例如性能分析,智能缩进帮助器和良好的自动完成支持

https://code.google.com/p/spyderlib/

I like Spyder, it has many tools, such as profiling, intelligent indentation helper and a good autocompletion support

https://code.google.com/p/spyderlib/


回答 9

如果您的IDE有预算,则应尝试Wingware Professional,请参阅wingware.com。

If you have a budget for your IDE, you should give Wingware Professional a try, see wingware.com .


回答 10

我用过WingIDE并感到非常高兴。Intellisense相当不错,其他一些东西虽然有些古怪,但总的来说这是一个非常有效的工具

I’ve used WingIDE and have been very happy. Intellisense is pretty good, some other things are a bit wacky but overall it’s a very productive tool


回答 11

如果您正在寻找一个交互式环境并且不需要编写模块代码,我建议使用IPython。尽管这是在考虑科学家/统计学家的前提下开发的,但是它在没有安装任何科学软件包的情况下也可以正常运行。这些功能强大,具有代码完成,集成的帮助,集成的调试等功能,并且可作为具有Markdown和MathJax集成的笔记本使用。到目前为止,对于那些需要强大功能而又不希望将MB的GUI加载到RAM的用户来说,这是最佳选择-由于它是基于浏览器的,因此可在您始终加载的 chrome / safari实例中使用。;-)

If you are looking for an interactive environment and not needing to code modules, I would suggest IPython. Though this is developed with scientists/statisticians in mind, it will run just as well without any of the scientific packages installed. The features are powerful, with code completion, integrated help, integrated debugging, etc., and it functions as a notebook with Markdown and MathJax integration. By far the best choice for those that need powerful features without wishing to load megabytes of GUI into RAM–since it is browser based, it is used in your always loaded chrome/safari instance. ;-)


回答 12

Eclipse PyDev插件。

http://pydev.sourceforge.net/


回答 13

因为您熟悉Eclipse,所以您可能对Pydev感兴趣

since you are familiar with Eclipse maybe you are interested in Pydev


回答 14

Netbeans对Python的支持非常好,并且提供了您正在寻找的大多数功能。

Python support on netbeans is surprisingly good, and comes with most of the features you’re looking for.


回答 15

TextMate或Panic的尾声。如果您需要功能完善的厨房水槽IDE,则NetBeans可以很好地工作。

TextMate or Panic’s Coda. NetBeans works very well, if you want a full-blown kitchen sink IDE.


回答 16

我已经在Google上搜索了类似这样的应用程序一段时间,但我发现只有界面笨拙的选项。

然后,我打开了Mac App Store,找到了CodeRunner。非常漂亮和干净的界面。支持多种语言,如Python,Lua,Perl,Ruby,Javascript等。价格为10美元,但值得!

I’ve searched on Google for an app like this for a while, and I’ve found only options with heavy and ugly interfaces.

Then I opened Mac App Store and found CodeRunner. Very nice and clean interface. Support many languages like Python, Lua, Perl, Ruby, Javascript, etc. The price is U$10, but it’s worth it!


回答 17

“ …的哪个编辑器/ IDE?” 是开始“我的狗比你的狗还漂亮”的长期方法。最棒的 如今,大多数vim向上的编辑器都可以使用,有很多不错的选择,甚至以C或Java工具开头的IDE都可以与Python和其他动态语言很好地兼容。

就是说,在尝试了许多IDE(Eclipse,NetBeans,XCode,Komodo,PyCharm等)之后,我成为ActiveState的Komodo IDE的粉丝。我主要在Mac OS X上使用它,尽管我在Windows上也使用了多年。一个许可证可将您带到任何平台。

Komodo与流行的ActiveState语言本身很好地集成在一起(尤其是Windows),与神话般的(和Pythonic的)Mercurial变更管理系统(以及其他)兼容,并且具有出色的处理核心任务的能力,例如代码编辑,语法着色,代码完成,实时语法检查和可视调试。在预集成的重构和代码检查工具(例如绳索,pylint)方面,它有点弱,但是它是可扩展的,并且具有集成外部工具和定制工具的良好功能。

我喜欢Komodo的某些方面超出了write-run-debug循环。自从动态语言成为趋势之前,ActiveState长期以来就一直为开发社区提供支持(例如,使用免费语言构建,软件包存储库,配方站点等)。基本的Komodo Edit编辑器是免费和开源的,是Mozilla Firefox技术的扩展。科莫多语是多国语言。我永远不会只做Python,Perl或其他任何事情。Komodo使用核心语言(Python,Perl,Ruby,PHP,JavaScript)以及支持语言(XML,XSLT,SQL,X / HTML,CSS),非动态语言(Java,C等)和帮助器( Makefile,INI和配置文件,shell脚本,自定义小语言等),其他人也可以做到这一点,但Komodo将它们全部放在一个地方,随时可以使用。它是动态语言的瑞士军刀。

Komodo IDE绝不是完美的,而编辑器/ IDE是YMMV的最终选择。但是我经常很高兴使用它,每年我都很高兴地重新获得支持订阅。的确,我只记得!这个月即将到来。信用卡:出。我与ActiveState没有任何商业联系,只是一个满意的客户。

“Which editor/IDE for …?” is a longstanding way to start a “My dog is too prettier than yours!” slapfest. Nowadays most editors from vim upwards can be used, there are multiple good alternatives, and even IDEs that started as C or Java tools work pretty well with Python and other dynamic languages.

That said, having tried a bunch of IDEs (Eclipse, NetBeans, XCode, Komodo, PyCharm, …), I am a fan of ActiveState’s Komodo IDE. I use it on Mac OS X primarily, though I’ve used it for years on Windows as well. The one license follows you to any platform.

Komodo is well-integrated with popular ActiveState builds of the languages themselves (esp. for Windows), works well with the fabulous (and Pythonic) Mercurial change management system (among others), and has good-to-excellent abilities for core tasks like code editing, syntax coloring, code completion, real-time syntax checking, and visual debugging. It is a little weak when it comes to pre-integrated refactoring and code-check tools (e.g. rope, pylint), but it is extensible and has a good facility for integrating external and custom tools.

Some of the things I like about Komodo go beyond the write-run-debug loop. ActiveState has long supported the development community (e.g. with free language builds, package repositories, a recipes site, …), since before dynamic languages were the trend. The base Komodo Edit editor is free and open source, an extension of Mozilla’s Firefox technologies. And Komodo is multi-lingual. I never end up doing just Python, just Perl, or just whatever. Komodo works with the core language (Python, Perl, Ruby, PHP, JavaScript) alongside supporting languages (XML, XSLT, SQL, X/HTML, CSS), non-dynamic languages (Java, C, etc.), and helpers (Makefiles, INI and config files, shell scripts, custom little languages, etc.) Others can do that too, but Komodo puts them all in once place, ready to go. It’s a Swiss Army Knife for dynamic languages. (This is contra PyCharm, e.g., which is great itself, but I’d need like a half-dozen of JetBrains’ individual IDEs to cover all the things I do).

Komodo IDE is by no means perfect, and editors/IDEs are the ultimate YMMV choice. But I am regularly delighted to use it, and every year I re-up my support subscription quite happily. Indeed, I just remembered! That’s coming up this month. Credit card: Out. I have no commercial connection to ActiveState–just a happy customer.


回答 18

您可能需要研究Eclim,这是一个Eclipse服务器,允许您从喜欢的文本编辑器中使用Eclipse功能。对于python相关功能,它在后台使用RopePyFlakesPyLint

You might want to look into Eclim, an Eclipse server that allows you to use Eclipse functionality from within your favorite text editor. For python-related functionality, it uses Rope, PyFlakes, and PyLint under the hood.


回答 19

我一直在使用的评估版Sublime Text。好的是它并没有真正过期。

到目前为止,一切都很好,而且非常容易上手。

I’ve been using an Evaluation copy of Sublime Text. What’s good is it doesn’t really expire.

It’s been good so far and was really easy to get started with.


回答 20

我为此可能会有点晚,但是我建议使用Aptana Studio3.x。它是基于eclipse的,并且可以随时使用python。对DJango, HTML5 and JQuery。对我来说,它是一个完美的Web开发工具。我也从事HTML5 and Android开发工作,因此无需切换其他IDE。这是我的多合一解决方案。

注意:您需要大量的RAM才能使它时髦!4+ GB太棒了!

I may be a little late for this, but I would recommend Aptana Studio 3.x . Its a based on eclipse and has everything ready-to-go for python. It has very good support for DJango, HTML5 and JQuery. For me its a perfect web-development tool. I do HTML5 and Android development too, this way I do not need to keep switching different IDE’s. It my all-in-one solution.

Note: you need a good amount of RAM for this to be snazzy !! 4+ GB is awesome !!


回答 21

Visual Studio代码 + 官方Python插件

在这里,您可以看到其当前Python功能的概述:

https://code.visualstudio.com/docs/languages/python

巧克力

http://chocolatapp.com

它轻巧,并提供代码完成功能。花费金钱。

编辑:显然,巧克力在2013年是一个有趣的选择,但此后许多其他人出现了,开发停滞了。如今,我建议使用Visual Studio Code + Python插件。

Visual Studio Code + Official Python Plugin

Here you see an overview of its current Python features:

https://code.visualstudio.com/docs/languages/python

Chocolat

http://chocolatapp.com

It’s lightweight and offers Code Completion. Costs money.

EDIT: Apparently Chocolat was an interesting option in 2013 but since then many others came up and development stalled. Nowadays I recommend Visual Studio Code + Python Plugin.


Python部门

问题:Python部门

我试图将一组从-100到0的数字归一化到10-100的范围,并且遇到了问题,只是注意到即使根本没有任何变量,这也无法评估我期望的方式:

>>> (20-10) / (100-10)
0

浮动划分也不起作用:

>>> float((20-10) / (100-10))
0.0

如果除法的任一侧都转换为浮点数,它将起作用:

>>> (20-10) / float((100-10))
0.1111111111111111

第一个示例中的每一边都被评估为一个int,这意味着最终答案将被强制转换为int。由于0.111小于.5,因此将其舍入为0。在我看来,这不是透明的,但我想是这样的。

有什么解释?

I was trying to normalize a set of numbers from -100 to 0 to a range of 10-100 and was having problems only to notice that even with no variables at all, this does not evaluate the way I would expect it to:

>>> (20-10) / (100-10)
0

Float division doesn’t work either:

>>> float((20-10) / (100-10))
0.0

If either side of the division is cast to a float it will work:

>>> (20-10) / float((100-10))
0.1111111111111111

Each side in the first example is evaluating as an int which means the final answer will be cast to an int. Since 0.111 is less than .5, it rounds to 0. It is not transparent in my opinion, but I guess that’s the way it is.

What is the explanation?


回答 0

您使用的是Python 2.x,其中整数除法将被截断而不是变成浮点数。

>>> 1 / 2
0

您应该将其中一个设为float

>>> float(10 - 20) / (100 - 10)
-0.1111111111111111

from __future__ import division,强制/采用总是返回float的Python 3.x行为。

>>> from __future__ import division
>>> (10 - 20) / (100 - 10)
-0.1111111111111111

You’re using Python 2.x, where integer divisions will truncate instead of becoming a floating point number.

>>> 1 / 2
0

You should make one of them a float:

>>> float(10 - 20) / (100 - 10)
-0.1111111111111111

or from __future__ import division, which the forces / to adopt Python 3.x’s behavior that always returns a float.

>>> from __future__ import division
>>> (10 - 20) / (100 - 10)
-0.1111111111111111

回答 1

将Integers放入其中,因此Python给了您一个整数

>>> 10 / 90
0

如果此后将其强制转换为浮点数,则四舍五入将已经完成,换句话说,0整数将始终变为0浮点数。

如果您在除法的任一侧使用浮点数,那么Python将为您提供您所期望的答案。

>>> 10 / 90.0
0.1111111111111111

因此,在您的情况下:

>>> float(20-10) / (100-10)
0.1111111111111111
>>> (20-10) / float(100-10)
0.1111111111111111

You’re putting Integers in so Python is giving you an integer back:

>>> 10 / 90
0

If if you cast this to a float afterwards the rounding will have already been done, in other words, 0 integer will always become 0 float.

If you use floats on either side of the division then Python will give you the answer you expect.

>>> 10 / 90.0
0.1111111111111111

So in your case:

>>> float(20-10) / (100-10)
0.1111111111111111
>>> (20-10) / float(100-10)
0.1111111111111111

回答 2

在进行除法之前,需要将其更改为浮点数。那是:

float(20 - 10) / (100 - 10)

You need to change it to a float BEFORE you do the division. That is:

float(20 - 10) / (100 - 10)

回答 3

在Python 2.7中,/如果输入为整数,则运算符为整数除法:

>>>20/15
1

>>>20.0/15.0
1.33333333333

>>>20.0/15
1.33333333333

在Python 3.3中,/即使输入是整数,运算符也是浮点除法。

>>> 20/15
1.33333333333

>>>20.0/15
1.33333333333

对于Python 3中的整数除法,我们将使用//运算符。

//运算符在Python 2.7和Python 3.3中都是整数除法运算符。

在Python 2.7和Python 3.3中:

>>>20//15
1

现在,看比较

>>>a = 7.0/4.0
>>>b = 7/4
>>>print a == b

对于上述程序,输出在Python 2.7中为False,在Python 3.3中为True。

在Python 2.7中a = 1.75和b = 1。

在Python 3.3中,a = 1.75和b = 1.75,仅因为/是一个浮点除法。

In Python 2.7, the / operator is an integer division if inputs are integers:

>>>20/15
1

>>>20.0/15.0
1.33333333333

>>>20.0/15
1.33333333333

In Python 3.3, the / operator is a float division even if the inputs are integer.

>>> 20/15
1.33333333333

>>>20.0/15
1.33333333333

For integer division in Python 3, we will use the // operator.

The // operator is an integer division operator in both Python 2.7 and Python 3.3.

In Python 2.7 and Python 3.3:

>>>20//15
1

Now, see the comparison

>>>a = 7.0/4.0
>>>b = 7/4
>>>print a == b

For the above program, the output will be False in Python 2.7 and True in Python 3.3.

In Python 2.7 a = 1.75 and b = 1.

In Python 3.3 a = 1.75 and b = 1.75, just because / is a float division.


回答 4

它与您使用的python版本有关。基本上,它采用C行为:如果将两个整数相除,结果将四舍五入为一个整数。还请记住,Python从左到右执行操作,这在您键入时发挥作用。

示例:由于这是我进行算术运算时总是会浮现的一个问题(我应该转换为浮点数和哪个数字),因此提供了一个来自该方面的示例:

>>> a = 1/2/3/4/5/4/3
>>> a
0

当我们将整数相除时,毫不奇怪的是,它会降低四舍五入。

>>> a = 1/2/3/4/5/4/float(3)
>>> a
0.0

如果我们强制转换要浮点数的最后一个整数,我们仍然会得到零,因为到我们的数字除以浮点数时,由于整数除法,该数字已经变为0。

>>> a = 1/2/3/float(4)/5/4/3
>>> a
0.0

与上述相同,但将float类型转换向左侧稍微移近。

>>> a = float(1)/2/3/4/5/4/3
>>> a
0.0006944444444444445

最后,当我们将第一个整数转换为浮点数时,结果是所需的整数,因为从第一个除法(即最左边的整数)开始,我们使用浮点数。

额外1:如果您尝试回答该问题以改善算术评估,则应检查此内容

附加2:请注意以下情况:

>>> a = float(1/2/3/4/5/4/3)
>>> a
0.0

It has to do with the version of python that you use. Basically it adopts the C behavior: if you divide two integers, the results will be rounded down to an integer. Also keep in mind that Python does the operations from left to right, which plays a role when you typecast.

Example: Since this is a question that always pops in my head when I am doing arithmetic operations (should I convert to float and which number), an example from that aspect is presented:

>>> a = 1/2/3/4/5/4/3
>>> a
0

When we divide integers, not surprisingly it gets lower rounded.

>>> a = 1/2/3/4/5/4/float(3)
>>> a
0.0

If we typecast the last integer to float, we will still get zero, since by the time our number gets divided by the float has already become 0 because of the integer division.

>>> a = 1/2/3/float(4)/5/4/3
>>> a
0.0

Same scenario as above but shifting the float typecast a little closer to the left side.

>>> a = float(1)/2/3/4/5/4/3
>>> a
0.0006944444444444445

Finally, when we typecast the first integer to float, the result is the desired one, since beginning from the first division, i.e. the leftmost one, we use floats.

Extra 1: If you are trying to answer that to improve arithmetic evaluation, you should check this

Extra 2: Please be careful of the following scenario:

>>> a = float(1/2/3/4/5/4/3)
>>> a
0.0

回答 5

通过放置“。”来指定浮点数 该数字之后也会导致其默认浮动。

>>> 1 / 2
0

>>> 1. / 2.
0.5

Specifying a float by placing a ‘.’ after the number will also cause it to default to float.

>>> 1 / 2
0

>>> 1. / 2.
0.5

回答 6

使其中至少一个浮点,然后将是浮点除法,而不是整数:

>>> (20.0-10) / (100-10)
0.1111111111111111

将结果强制转换为浮点型为时已晚。

Make at least one of them float, then it will be float division, not integer:

>>> (20.0-10) / (100-10)
0.1111111111111111

Casting the result to float is too late.


回答 7

在python中cv2未更新除法计算。因此,您必须将其包括from __future__ import division 在程序的第一行中。

In python cv2 not updated the division calculation. so, you must include from __future__ import division in first line of the program.


回答 8

无论哪种方式,它都是整数除法。10/90 =0。在第二种情况下,您只是将0强制转换为浮点数。

尝试将“ /”的操作数之一强制转换为浮点数:

float(20-10) / (100-10)

Either way, it’s integer division. 10/90 = 0. In the second case, you’re merely casting 0 to a float.

Try casting one of the operands of “/” to be a float:

float(20-10) / (100-10)

回答 9

在第二个示例中,除法已经发生,您正在转换为浮动。试试这个:

float(20-10) / float(100-10)

You’re casting to float after the division has already happened in your second example. Try this:

float(20-10) / float(100-10)

回答 10

令我惊讶的是,没有人提到原始海报可能喜欢有理数。如果您对此感兴趣,基于Python的程序Sage会为您服务。(尽管3.x正在开发中,但目前仍基于Python2.x。)

sage: (20-10) / (100-10)
1/9

这不是每个人的解决方案,因为它会做一些准备工作,所以这些数字不是intSage Integer类元素。尽管如此,值得一提的是Python生态系统的一部分。

I’m somewhat surprised that no one has mentioned that the original poster might have liked rational numbers to result. Should you be interested in this, the Python-based program Sage has your back. (Currently still based on Python 2.x, though 3.x is under way.)

sage: (20-10) / (100-10)
1/9

This isn’t a solution for everyone, because it does do some preparsing so these numbers aren’t ints, but Sage Integer class elements. Still, worth mentioning as a part of the Python ecosystem.


回答 11

我个人更喜欢1. *在开始时插入一个。所以表达式变成了这样的东西:

1. * (20-10) / (100-10)

因为我总是对某些公式进行除法,例如:

accuracy = 1. * (len(y_val) - sum(y_val)) / len(y_val)

因此不可能简单地添加一个.0like 20.0。就我而言,用a换行float()可能会失去一点可读性。

Personally I preferred to insert a 1. * at the very beginning. So the expression become something like this:

1. * (20-10) / (100-10)

As I always do a division for some formula like:

accuracy = 1. * (len(y_val) - sum(y_val)) / len(y_val)

so it is impossible to simply add a .0 like 20.0. And in my case, wrapping with a float() may lose a little bit readability.


检查网络连接

问题:检查网络连接

我想看看是否可以访问在线API,但是为此我需要访问Internet。

如何使用Python查看是否存在可用的活动连接?

I want to see if I can access an online API, but for that I need to have Internet access.

How can I see if there’s a connection available and active using Python?


回答 0

也许您可以使用如下方式:

import urllib2

def internet_on():
    try:
        urllib2.urlopen('http://216.58.192.142', timeout=1)
        return True
    except urllib2.URLError as err: 
        return False

目前,216.58.192.142是google.com的IP地址之一。更改http://216.58.192.142到任何可以期望快速响应的站点

此固定IP不会永远映射到google.com。因此,此代码并不健壮-需要不断维护才能使其正常运行。

上面的代码使用固定IP地址而不是完全限定域名(FQDN)的原因是,FQDN需要进行DNS查找。当机器没有有效的Internet连接时,DNS查找本身可能会阻止呼叫urllib_request.urlopen超过一秒钟。感谢@rzetterberg指出这一点。


如果上面的固定IP地址不起作用,您可以通过运行以下命令找到google.com的当前IP地址(在Unix上)

% dig google.com  +trace 
...
google.com.     300 IN  A   216.58.192.142

Perhaps you could use something like this:

import urllib2

def internet_on():
    try:
        urllib2.urlopen('http://216.58.192.142', timeout=1)
        return True
    except urllib2.URLError as err: 
        return False

Currently, 216.58.192.142 is one of the IP addresses for google.com. Change http://216.58.192.142 to whatever site can be expected to respond quickly.

This fixed IP will not map to google.com forever. So this code is not robust — it will need constant maintenance to keep it working.

The reason why the code above uses a fixed IP address instead of fully qualified domain name (FQDN) is because a FQDN would require a DNS lookup. When the machine does not have a working internet connection, the DNS lookup itself may block the call to urllib_request.urlopen for more than a second. Thanks to @rzetterberg for pointing this out.


If the fixed IP address above is not working, you can find a current IP address for google.com (on unix) by running

% dig google.com  +trace 
...
google.com.     300 IN  A   216.58.192.142

回答 1

如果我们可以连接到某些Internet服务器,那么我们确实具有连接性。但是,对于最快,最可靠的方法,所有解决方案至少应符合以下要求:

  • 避免使用DNS解析(我们将需要一个众所周知的IP,并保证其在大多数时间都可用)
  • 避免应用程序层连接(连接到HTTP / FTP / IMAP服务)
  • 避免从Python或其他选择的语言调用外部实用程序(我们需要提出一种与语言无关的解决方案,该解决方案不依赖第三方解决方案)

为了符合这些要求,一种方法可能是检查是否可以访问Google的公共DNS服务器之一。这些服务器的IPv4地址为8.8.8.88.8.4.4。我们可以尝试连接到其中任何一个。

主机的快速Nmap 8.8.8.8给出以下结果:

$ sudo nmap 8.8.8.8

Starting Nmap 6.40 ( http://nmap.org ) at 2015-10-14 10:17 IST
Nmap scan report for google-public-dns-a.google.com (8.8.8.8)
Host is up (0.0048s latency).
Not shown: 999 filtered ports
PORT   STATE SERVICE
53/tcp open  domain

Nmap done: 1 IP address (1 host up) scanned in 23.81 seconds

如我们所见,它53/tcp是开放的且未过滤。如果您是非root用户,请记住使用sudo-Pn参数Nmap发送精心制作的探测数据包并确定主机是否启动。

在尝试使用Python之前,让我们使用外部工具Netcat测试连接性:

$ nc 8.8.8.8 53 -zv
Connection to 8.8.8.8 53 port [tcp/domain] succeeded!

Netcat的确认,我们可以达到8.8.8.853/tcp。现在,我们可以8.8.8.8:53/tcp在Python中设置与的套接字连接以检查连接:

import socket

def internet(host="8.8.8.8", port=53, timeout=3):
    """
    Host: 8.8.8.8 (google-public-dns-a.google.com)
    OpenPort: 53/tcp
    Service: domain (DNS/TCP)
    """
    try:
        socket.setdefaulttimeout(timeout)
        socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect((host, port))
        return True
    except socket.error as ex:
        print(ex)
        return False

internet()

另一种方法可能是将手动制作的DNS探针发送到这些服务器之一,然后等待响应。但是,我认为,由于数据包丢失,DNS解析失败等原因,相比而言,它可能会比较慢。如果您另有意见,请发表评论。

更新#1:感谢@theamk的注释,超时现在是一个参数,3s默认情况下初始化为。

更新#2:我进行了快速测试,以找出对该问题所有有效答案的最快,最通用的实现。总结如下:

$ ls *.py | sort -n | xargs -I % sh -c 'echo %; ./timeit.sh %; echo'
defos.py
True
00:00:00:00.487

iamaziz.py
True
00:00:00:00.335

ivelin.py
True
00:00:00:00.105

jaredb.py
True
00:00:00:00.533

kevinc.py
True
00:00:00:00.295

unutbu.py
True
00:00:00:00.546

7h3rAm.py
True
00:00:00:00.032

再一次:

$ ls *.py | sort -n | xargs -I % sh -c 'echo %; ./timeit.sh %; echo'
defos.py
True
00:00:00:00.450

iamaziz.py
True
00:00:00:00.358

ivelin.py
True
00:00:00:00.099

jaredb.py
True
00:00:00:00.585

kevinc.py
True
00:00:00:00.492

unutbu.py
True
00:00:00:00.485

7h3rAm.py
True
00:00:00:00.035

True上面的输出中的数字表示来自各个作者的所有这些实现均正确地标识了与Internet的连接。时间以毫秒为单位显示。

更新#3:异常处理更改后再次进行测试:

defos.py
True
00:00:00:00.410

iamaziz.py
True
00:00:00:00.240

ivelin.py
True
00:00:00:00.109

jaredb.py
True
00:00:00:00.520

kevinc.py
True
00:00:00:00.317

unutbu.py
True
00:00:00:00.436

7h3rAm.py
True
00:00:00:00.030

If we can connect to some Internet server, then we indeed have connectivity. However, for the fastest and most reliable approach, all solutions should comply with the following requirements, at the very least:

  • Avoid DNS resolution (we will need an IP that is well-known and guaranteed to be available for most of the time)
  • Avoid application layer connections (connecting to an HTTP/FTP/IMAP service)
  • Avoid calls to external utilities from Python or other language of choice (we need to come up with a language-agnostic solution that doesn’t rely on third-party solutions)

To comply with these, one approach could be to, check if one of the Google’s public DNS servers is reachable. The IPv4 addresses for these servers are 8.8.8.8 and 8.8.4.4. We can try connecting to any of them.

A quick Nmap of the host 8.8.8.8 gave below result:

$ sudo nmap 8.8.8.8

Starting Nmap 6.40 ( http://nmap.org ) at 2015-10-14 10:17 IST
Nmap scan report for google-public-dns-a.google.com (8.8.8.8)
Host is up (0.0048s latency).
Not shown: 999 filtered ports
PORT   STATE SERVICE
53/tcp open  domain

Nmap done: 1 IP address (1 host up) scanned in 23.81 seconds

As we can see, 53/tcp is open and non-filtered. If you are a non-root user, remember to use sudo or the -Pn argument for Nmap to send crafted probe packets and determine if a host is up.

Before we try with Python, let’s test connectivity using an external tool, Netcat:

$ nc 8.8.8.8 53 -zv
Connection to 8.8.8.8 53 port [tcp/domain] succeeded!

Netcat confirms that we can reach 8.8.8.8 over 53/tcp. Now we can set up a socket connection to 8.8.8.8:53/tcp in Python to check connection:

import socket

def internet(host="8.8.8.8", port=53, timeout=3):
    """
    Host: 8.8.8.8 (google-public-dns-a.google.com)
    OpenPort: 53/tcp
    Service: domain (DNS/TCP)
    """
    try:
        socket.setdefaulttimeout(timeout)
        socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect((host, port))
        return True
    except socket.error as ex:
        print(ex)
        return False

internet()

Another approach could be to send a manually crafted DNS probe to one of these servers and wait for a response. But, I assume, it might prove slower in comparison due to packet drops, DNS resolution failure, etc. Please comment if you think otherwise.

UPDATE #1: Thanks to @theamk’s comment, timeout is now an argument and initialized to 3s by default.

UPDATE #2: I did quick tests to identify the fastest and most generic implementation of all valid answers to this question. Here’s the summary:

$ ls *.py | sort -n | xargs -I % sh -c 'echo %; ./timeit.sh %; echo'
defos.py
True
00:00:00:00.487

iamaziz.py
True
00:00:00:00.335

ivelin.py
True
00:00:00:00.105

jaredb.py
True
00:00:00:00.533

kevinc.py
True
00:00:00:00.295

unutbu.py
True
00:00:00:00.546

7h3rAm.py
True
00:00:00:00.032

And once more:

$ ls *.py | sort -n | xargs -I % sh -c 'echo %; ./timeit.sh %; echo'
defos.py
True
00:00:00:00.450

iamaziz.py
True
00:00:00:00.358

ivelin.py
True
00:00:00:00.099

jaredb.py
True
00:00:00:00.585

kevinc.py
True
00:00:00:00.492

unutbu.py
True
00:00:00:00.485

7h3rAm.py
True
00:00:00:00.035

True in the above output signifies that all these implementations from respective authors correctly identify connectivity to the Internet. Time is shown with milliseconds resolution.

UPDATE #3: Tested again after the exception handling change:

defos.py
True
00:00:00:00.410

iamaziz.py
True
00:00:00:00.240

ivelin.py
True
00:00:00:00.109

jaredb.py
True
00:00:00:00.520

kevinc.py
True
00:00:00:00.317

unutbu.py
True
00:00:00:00.436

7h3rAm.py
True
00:00:00:00.030

回答 2

仅发出HEAD请求会更快,因此不会获取HTML。
我也相信谷歌会更喜欢这种方式:)

try:
    import httplib
except:
    import http.client as httplib

def have_internet():
    conn = httplib.HTTPConnection("www.google.com", timeout=5)
    try:
        conn.request("HEAD", "/")
        conn.close()
        return True
    except:
        conn.close()
        return False

It will be faster to just make a HEAD request so no HTML will be fetched.
Also I am sure google would like it better this way :)

try:
    import httplib
except:
    import http.client as httplib

def have_internet():
    conn = httplib.HTTPConnection("www.google.com", timeout=5)
    try:
        conn.request("HEAD", "/")
        conn.close()
        return True
    except:
        conn.close()
        return False

回答 3

作为ubutnu / Kevin C答案的替代方法,我使用以下requests软件包:

import requests

def connected_to_internet(url='http://www.google.com/', timeout=5):
    try:
        _ = requests.get(url, timeout=timeout)
        return True
    except requests.ConnectionError:
        print("No internet connection available.")
    return False

奖励:可以扩展为对网站执行ping操作的功能。

def web_site_online(url='http://www.google.com/', timeout=5):
    try:
        req = requests.get(url, timeout=timeout)
        # HTTP errors are not raised by default, this statement does that
        req.raise_for_status()
        return True
    except requests.HTTPError as e:
        print("Checking internet connection failed, status code {0}.".format(
        e.response.status_code))
    except requests.ConnectionError:
        print("No internet connection available.")
    return False

As an alternative to ubutnu’s/Kevin C answers, I use the requests package like this:

import requests

def connected_to_internet(url='http://www.google.com/', timeout=5):
    try:
        _ = requests.head(url, timeout=timeout)
        return True
    except requests.ConnectionError:
        print("No internet connection available.")
    return False

Bonus: this can be extended to this function that pings a website.

def web_site_online(url='http://www.google.com/', timeout=5):
    try:
        req = requests.head(url, timeout=timeout)
        # HTTP errors are not raised by default, this statement does that
        req.raise_for_status()
        return True
    except requests.HTTPError as e:
        print("Checking internet connection failed, status code {0}.".format(
        e.response.status_code))
    except requests.ConnectionError:
        print("No internet connection available.")
    return False

回答 4

只是为了更新unutbu所说的Python 3.2中的新代码

def check_connectivity(reference):
    try:
        urllib.request.urlopen(reference, timeout=1)
        return True
    except urllib.request.URLError:
        return False

而且,请注意,这里的输入(参考)是您要检查的网址:我建议选择一种可以快速连接您所住的地方的东西-即我住在韩国,因此我可能会将参考设置为http:/ /www.naver.com

Just to update what unutbu said for new code in Python 3.2

def check_connectivity(reference):
    try:
        urllib.request.urlopen(reference, timeout=1)
        return True
    except urllib.request.URLError:
        return False

And, just to note, the input here (reference) is the url that you want to check: I suggest choosing something that connects fast where you live — i.e. I live in South Korea, so I would probably set reference to http://www.naver.com.


回答 5

您可以尝试下载数据,如果连接失败,您将知道连接不正常。

基本上,您无法检查计算机是否已连接到Internet。失败的原因可能有很多,例如错误的DNS配置,防火墙,NAT。因此,即使您进行了一些测试,也无法保证您可以尝试使用API​​进行连接。

You can just try to download data, and if connection fail you will know that somethings with connection isn’t fine.

Basically you can’t check if computer is connected to internet. There can be many reasons for failure, like wrong DNS configuration, firewalls, NAT. So even if you make some tests, you can’t have guaranteed that you will have connection with your API until you try.


回答 6

import urllib

def connected(host='http://google.com'):
    try:
        urllib.urlopen(host)
        return True
    except:
        return False

# test
print( 'connected' if connected() else 'no internet!' )

对于python 3,请使用 urllib.request.urlopen(host)

import urllib

def connected(host='http://google.com'):
    try:
        urllib.urlopen(host)
        return True
    except:
        return False

# test
print( 'connected' if connected() else 'no internet!' )

For python 3, use urllib.request.urlopen(host)


回答 7

无论如何,请尝试尝试执行的操作。如果失败,python应该抛出一个异常让您知道。

要首先尝试一些琐碎的操作来检测连接,将引入竞争条件。如果您在测试时互联网连接有效但在需要进行实际工作之前就断开了怎么办?

Try the operation you were attempting to do anyway. If it fails python should throw you an exception to let you know.

To try some trivial operation first to detect a connection will be introducing a race condition. What if the internet connection is valid when you test but goes down before you need to do actual work?


回答 8

如果本地主机已从“ 127.0.0.1 尝试”中更改,则这可能不起作用

import socket
ipaddress=socket.gethostbyname(socket.gethostname())
if ipaddress=="127.0.0.1":
    print("You are not connected to the internet!")
else:
    print("You are connected to the internet with the IP address of "+ ipaddress )

除非进行编辑,否则当您未连接到Internet时,您的计算机IP将为127.0.0.1。该代码基本上获取IP地址,然后询问它是否是localhost IP地址。希望能有所帮助

This might not work if the localhost has been changed from 127.0.0.1 Try

import socket
ipaddress=socket.gethostbyname(socket.gethostname())
if ipaddress=="127.0.0.1":
    print("You are not connected to the internet!")
else:
    print("You are connected to the internet with the IP address of "+ ipaddress )

Unless edited , your computers IP will be 127.0.0.1 when not connected to the internet. This code basically gets the IP address and then asks if it is the localhost IP address . Hope that helps


回答 9

这是我的版本

import requests

try:
    if requests.get('https://google.com').ok:
        print("You're Online")
except:
    print("You're Offline")

Here’s my version

import requests

try:
    if requests.get('https://google.com').ok:
        print("You're Online")
except:
    print("You're Offline")

回答 10

具有以下优点的现代便携式解决方案requests

import requests

def internet():
    """Detect an internet connection."""

    connection = None
    try:
        r = requests.get("https://google.com")
        r.raise_for_status()
        print("Internet connection detected.")
        connection = True
    except:
        print("Internet connection not detected.")
        connection = False
    finally:
        return connection

或者,一个引发异常的版本:

import requests
from requests.exceptions import ConnectionError

def internet():
    """Detect an internet connection."""

    try:
        r = requests.get("https://google.com")
        r.raise_for_status()
        print("Internet connection detected.")
    except ConnectionError as e:
        print("Internet connection not detected.")
        raise e

A modern portable solution with requests:

import requests

def internet():
    """Detect an internet connection."""

    connection = None
    try:
        r = requests.get("https://google.com")
        r.raise_for_status()
        print("Internet connection detected.")
        connection = True
    except:
        print("Internet connection not detected.")
        connection = False
    finally:
        return connection

Or, a version that raises an exception:

import requests
from requests.exceptions import ConnectionError

def internet():
    """Detect an internet connection."""

    try:
        r = requests.get("https://google.com")
        r.raise_for_status()
        print("Internet connection detected.")
    except ConnectionError as e:
        print("Internet connection not detected.")
        raise e

回答 11

最好的方法是让它检查python在找不到网站时始终提供的IP地址。在这种情况下,这是我的代码:

import socket

print("website connection checker")
while True:
    website = input("please input website: ")
    print("")
    print(socket.gethostbyname(website))
    if socket.gethostbyname(website) == "92.242.140.2":
        print("Website could be experiencing an issue/Doesn't exist")
    else:
        socket.gethostbyname(website)
        print("Website is operational!")
        print("")

Best way to do this is to make it check against an IP address that python always gives if it can’t find the website. In this case this is my code:

import socket

print("website connection checker")
while True:
    website = input("please input website: ")
    print("")
    print(socket.gethostbyname(website))
    if socket.gethostbyname(website) == "92.242.140.2":
        print("Website could be experiencing an issue/Doesn't exist")
    else:
        socket.gethostbyname(website)
        print("Website is operational!")
        print("")

回答 12

我最喜欢的一个,是否在群集上运行脚本

import subprocess

def online(timeout):
    try:
        return subprocess.run(
            ['wget', '-q', '--spider', 'google.com'],
            timeout=timeout
        ).returncode == 0
    except subprocess.TimeoutExpired:
        return False

这会安静地运行wget,不下载任何东西,而是检查给定的远程文件在网络上是否存在

my favorite one, when running scripts on a cluster or not

import subprocess

def online(timeout):
    try:
        return subprocess.run(
            ['wget', '-q', '--spider', 'google.com'],
            timeout=timeout
        ).returncode == 0
    except subprocess.TimeoutExpired:
        return False

this runs wget quietly, not downloading anything but checking that the given remote file exists on the web


回答 13

unutbu的回答为起点,并且过去因“静态” IP地址更改而烦恼,我制作了一个简单的类,该类使用DNS查找(即,使用URL“ https:// www .google.com “),然后存储响应服务器的IP地址,以用于后续检查。这样,IP地址始终是最新的(假设该类至少每隔几年左右重新初始化一次)。对于这个答案,我也给予了很高的评价,它向我展示了如何获取服务器的IP地址(进行任何重定向等之后)。请忽略此解决方案的明显缺陷,在这里我将举一个最小的工作示例。:)

这是我所拥有的:

import socket

try:
    from urllib2 import urlopen, URLError
    from urlparse import urlparse
except ImportError:  # Python 3
    from urllib.parse import urlparse
    from urllib.request import urlopen, URLError

class InternetChecker(object):
    conn_url = 'https://www.google.com/'

    def __init__(self):
        pass

    def test_internet(self):
        try:
            data = urlopen(self.conn_url, timeout=5)
        except URLError:
            return False

        try:
            host = data.fp._sock.fp._sock.getpeername()
        except AttributeError:  # Python 3
            host = data.fp.raw._sock.getpeername()

        # Ensure conn_url is an IPv4 address otherwise future queries will fail
        self.conn_url = 'http://' + (host[0] if len(host) == 2 else
                                     socket.gethostbyname(urlparse(data.geturl()).hostname))

        return True

# Usage example
checker = InternetChecker()
checker.test_internet()

Taking unutbu’s answer as a starting point, and having been burned in the past by a “static” IP address changing, I’ve made a simple class that checks once using a DNS lookup (i.e., using the URL “https://www.google.com“), and then stores the IP address of the responding server for use on subsequent checks. That way, the IP address is always up to date (assuming the class is re-initialized at least once every few years or so). I also give credit to gawry for this answer, which showed me how to get the server’s IP address (after any redirection, etc.). Please disregard the apparent hackiness of this solution, I’m going for a minimal working example here. :)

Here is what I have:

import socket

try:
    from urllib2 import urlopen, URLError
    from urlparse import urlparse
except ImportError:  # Python 3
    from urllib.parse import urlparse
    from urllib.request import urlopen, URLError

class InternetChecker(object):
    conn_url = 'https://www.google.com/'

    def __init__(self):
        pass

    def test_internet(self):
        try:
            data = urlopen(self.conn_url, timeout=5)
        except URLError:
            return False

        try:
            host = data.fp._sock.fp._sock.getpeername()
        except AttributeError:  # Python 3
            host = data.fp.raw._sock.getpeername()

        # Ensure conn_url is an IPv4 address otherwise future queries will fail
        self.conn_url = 'http://' + (host[0] if len(host) == 2 else
                                     socket.gethostbyname(urlparse(data.geturl()).hostname))

        return True

# Usage example
checker = InternetChecker()
checker.test_internet()

回答 14

采纳“第六”的答案,我认为我们可以以某种方式简化这一重要问题,因为新来者在技术问题上迷失了。

在这里,我最终将用来等待每天一次建立连接(3G,速度很慢)以进行PV监控的设备。

使用Raspbian 3.4.2在Pyth3下工作

from urllib.request import urlopen
from time import sleep
urltotest=http://www.lsdx.eu             # my own web page
nboftrials=0
answer='NO'
while answer=='NO' and nboftrials<10:
    try:
        urlopen(urltotest)
        answer='YES'
    except:
        essai='NO'
        nboftrials+=1
        sleep(30)       

最长运行时间:如果达到5分钟,我会在一个小时的时间内尝试尝试,但这又是另一段脚本!

Taking Six’ answer I think we could simplify somehow, an important issue as newcomers are lost in highly technical matters.

Here what I finally will use to wait for my connection (3G, slow) to be established once a day for my PV monitoring.

Works under Pyth3 with Raspbian 3.4.2

from urllib.request import urlopen
from time import sleep
urltotest=http://www.lsdx.eu             # my own web page
nboftrials=0
answer='NO'
while answer=='NO' and nboftrials<10:
    try:
        urlopen(urltotest)
        answer='YES'
    except:
        essai='NO'
        nboftrials+=1
        sleep(30)       

maximum running: 5 minutes if reached I will try in one hour’s time but its another bit of script!


回答 15

接受Ivelin的回答并添加一些额外的检查,因为我的路由器在查询google.com时会提供其ip地址192.168.0.1,如果没有互联网连接,则返回head。

import socket

def haveInternet():
    try:
        # first check if we get the correct IP-Address or just the router's IP-Address
        info = socket.getaddrinfo("www.google.com", None)[0]
        ipAddr = info[4][0]
        if ipAddr == "192.168.0.1" :
            return False
    except:
        return False

    conn = httplib.HTTPConnection("www.google.com", timeout=5)
    try:
        conn.request("HEAD", "/")
        conn.close()
        return True
    except:
        conn.close()
        return False

Taking Ivelin’s answer and add some extra check as my router delivers its ip address 192.168.0.1 and returns a head if it has no internet connection when querying google.com.

import socket

def haveInternet():
    try:
        # first check if we get the correct IP-Address or just the router's IP-Address
        info = socket.getaddrinfo("www.google.com", None)[0]
        ipAddr = info[4][0]
        if ipAddr == "192.168.0.1" :
            return False
    except:
        return False

    conn = httplib.HTTPConnection("www.google.com", timeout=5)
    try:
        conn.request("HEAD", "/")
        conn.close()
        return True
    except:
        conn.close()
        return False

回答 16

这在Python3.6中对我有用

import urllib
from urllib.request import urlopen


def is_internet():
    """
    Query internet using python
    :return:
    """
    try:
        urlopen('https://www.google.com', timeout=1)
        return True
    except urllib.error.URLError as Error:
        print(Error)
        return False


if is_internet():
    print("Internet is active")
else:
    print("Internet disconnected")

This works for me in Python3.6

import urllib
from urllib.request import urlopen


def is_internet():
    """
    Query internet using python
    :return:
    """
    try:
        urlopen('https://www.google.com', timeout=1)
        return True
    except urllib.error.URLError as Error:
        print(Error)
        return False


if is_internet():
    print("Internet is active")
else:
    print("Internet disconnected")

回答 17

我在Joel的代码中添加了一些内容。

    import socket,time
    mem1 = 0
    while True:
        try:
                host = socket.gethostbyname("www.google.com") #Change to personal choice of site
                s = socket.create_connection((host, 80), 2)
                s.close()
                mem2 = 1
                if (mem2 == mem1):
                    pass #Add commands to be executed on every check
                else:
                    mem1 = mem2
                    print ("Internet is working") #Will be executed on state change

        except Exception as e:
                mem2 = 0
                if (mem2 == mem1):
                    pass
                else:
                    mem1 = mem2
                    print ("Internet is down")
        time.sleep(10) #timeInterval for checking

I added a few to Joel’s code.

    import socket,time
    mem1 = 0
    while True:
        try:
                host = socket.gethostbyname("www.google.com") #Change to personal choice of site
                s = socket.create_connection((host, 80), 2)
                s.close()
                mem2 = 1
                if (mem2 == mem1):
                    pass #Add commands to be executed on every check
                else:
                    mem1 = mem2
                    print ("Internet is working") #Will be executed on state change

        except Exception as e:
                mem2 = 0
                if (mem2 == mem1):
                    pass
                else:
                    mem1 = mem2
                    print ("Internet is down")
        time.sleep(10) #timeInterval for checking

回答 18

对于我的项目,我使用修改后的脚本来ping google公用DNS服务器8.8.8.8。使用1秒超时和核心python库,没有外部依赖项:

import struct
import socket
import select


def send_one_ping(to='8.8.8.8'):
   ping_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.getprotobyname('icmp'))
   checksum = 49410
   header = struct.pack('!BBHHH', 8, 0, checksum, 0x123, 1)
   data = b'BCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwx'
   header = struct.pack(
      '!BBHHH', 8, 0, checksum, 0x123, 1
   )
   packet = header + data
   ping_socket.sendto(packet, (to, 1))
   inputready, _, _ = select.select([ping_socket], [], [], 1.0)
   if inputready == []:
      raise Exception('No internet') ## or return False
   _, address = ping_socket.recvfrom(2048)
   print(address) ## or return True


send_one_ping()

选择超时值是1,但也可以是选择的浮点数比在此实例中1秒更容易失败。

For my projects I use script modified to ping the google public DNS server 8.8.8.8. Using a timeout of 1 second and core python libraries with no external dependencies:

import struct
import socket
import select


def send_one_ping(to='8.8.8.8'):
   ping_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.getprotobyname('icmp'))
   checksum = 49410
   header = struct.pack('!BBHHH', 8, 0, checksum, 0x123, 1)
   data = b'BCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwx'
   header = struct.pack(
      '!BBHHH', 8, 0, checksum, 0x123, 1
   )
   packet = header + data
   ping_socket.sendto(packet, (to, 1))
   inputready, _, _ = select.select([ping_socket], [], [], 1.0)
   if inputready == []:
      raise Exception('No internet') ## or return False
   _, address = ping_socket.recvfrom(2048)
   print(address) ## or return True


send_one_ping()

The select timeout value is 1, but can be a floating point number of choice to fail more readily than the 1 second in this example.


回答 19

导入请求并尝试使用此简单的python代码。

def check_internet():
url = 'http://www.google.com/'
timeout = 5
try:
    _ = requests.get(url, timeout=timeout)
    return True
except requests.ConnectionError:
return False

import requests and try this simple python code.

def check_internet():
    url = 'http://www.google.com/'
    timeout = 5
    try:
        _ = requests.get(url, timeout=timeout)
        return True
    except requests.ConnectionError:
        return False

如何使用PIL裁剪图像?

问题:如何使用PIL裁剪图像?

我想通过从给定图像中删除前30行和后30行来裁剪图像。我已经搜索过,但没有得到确切的解决方案。有人有建议吗?

I want to crop image in the way by removing first 30 rows and last 30 rows from the given image. I have searched but did not get the exact solution. Does somebody have some suggestions?


回答 0

有一种crop()方法:

w, h = yourImage.size
yourImage.crop((0, 30, w, h-30)).save(...)

There is a crop() method:

w, h = yourImage.size
yourImage.crop((0, 30, w, h-30)).save(...)

回答 1

您需要为此导入PIL(枕头)。假设您的图像尺寸为1200、1600。我们会将图像从400、400裁剪为800、800

from PIL import Image
img = Image.open("ImageName.jpg")
area = (400, 400, 800, 800)
cropped_img = img.crop(area)
cropped_img.show()

You need to import PIL (Pillow) for this. Suppose you have an image of size 1200, 1600. We will crop image from 400, 400 to 800, 800

from PIL import Image
img = Image.open("ImageName.jpg")
area = (400, 400, 800, 800)
cropped_img = img.crop(area)
cropped_img.show()

回答 2

(左,上,右,下)表示两个点,

  1. (左上)
  2. (右下)

对于800×600像素的图像,图像的左上点是(0,0),右下点是(800,600)。

因此,为了将图像减半:

from PIL import Image
img = Image.open("ImageName.jpg")

img_left_area = (0, 0, 400, 600)
img_right_area = (400, 0, 800, 600)

img_left = img.crop(img_left_area)
img_right = img.crop(img_right_area)

img_left.show()
img_right.show()

坐标系

Python Imaging Library使用笛卡尔像素坐标系,左上角为(0,0)。注意,坐标指的是隐含的像素角。寻址为(0,0)的像素的中心实际上位于(0.5,0.5)。

坐标通常以2元组(x,y)的形式传递给库。矩形用4元组表示,左上角在前。例如,将覆盖所有800×600像素图像的矩形写为(0,0,800,600)。

(left, upper, right, lower) means two points,

  1. (left, upper)
  2. (right, lower)

with an 800×600 pixel image, the image’s left upper point is (0, 0), the right lower point is (800, 600).

So, for cutting the image half:

from PIL import Image
img = Image.open("ImageName.jpg")

img_left_area = (0, 0, 400, 600)
img_right_area = (400, 0, 800, 600)

img_left = img.crop(img_left_area)
img_right = img.crop(img_right_area)

img_left.show()
img_right.show()

Coordinate System

The Python Imaging Library uses a Cartesian pixel coordinate system, with (0,0) in the upper left corner. Note that the coordinates refer to the implied pixel corners; the centre of a pixel addressed as (0, 0) actually lies at (0.5, 0.5).

Coordinates are usually passed to the library as 2-tuples (x, y). Rectangles are represented as 4-tuples, with the upper left corner given first. For example, a rectangle covering all of an 800×600 pixel image is written as (0, 0, 800, 600).


回答 3

一种更简单的方法是使用ImageOps中的作物。您可以从每一侧输入要裁剪的像素数。

from PIL import ImageOps

border = (0, 30, 0, 30) # left, up, right, bottom
ImageOps.crop(img, border)

An easier way to do this is using crop from ImageOps. You can feed the number of pixels you want to crop from each side.

from PIL import ImageOps

border = (0, 30, 0, 30) # left, up, right, bottom
ImageOps.crop(img, border)

有趣好用的Python教程

退出移动版
微信支付
请使用 微信 扫码支付