分类目录归档:知识问答

如何清除解释器控制台?

问题:如何清除解释器控制台?

像大多数Python开发人员一样,我通常会打开一个控制台窗口,并运行Python解释器来测试命令,dir()东西help() stuff等。

像任何控制台一样,一段时间后,过去的命令和打印的可见积压会变得混乱,有时在多次重新运行同一命令时会造成混乱。我想知道是否以及如何清除Python解释器控制台。

我听说过要进行系统调用,然后cls在Windows或clearLinux 上进行调用,但是我希望可以命令解释器自己执行一些操作。

注意:我在Windows上运行,因此Ctrl+L无法正常工作。

Like most Python developers, I typically keep a console window open with the Python interpreter running to test commands, dir() stuff, help() stuff, etc.

Like any console, after a while the visible backlog of past commands and prints gets to be cluttered, and sometimes confusing when re-running the same command several times. I’m wondering if, and how, to clear the Python interpreter console.

I’ve heard about doing a system call and either calling cls on Windows or clear on Linux, but I was hoping there was something I could command the interpreter itself to do.

Note: I’m running on Windows, so Ctrl+L doesn’t work.


回答 0

如前所述,您可以进行系统调用:

对于Windows

>>> import os
>>> clear = lambda: os.system('cls')
>>> clear()

对于Linux,lambda变为

>>> clear = lambda: os.system('clear')

As you mentioned, you can do a system call:

For Windows

>>> import os
>>> clear = lambda: os.system('cls')
>>> clear()

For Linux the lambda becomes

>>> clear = lambda: os.system('clear')

回答 1

这里有一些方便的东西,它是跨平台的

import os

def cls():
    os.system('cls' if os.name=='nt' else 'clear')

# now, to clear the screen
cls()

here something handy that is a little more cross-platform

import os

def cls():
    os.system('cls' if os.name=='nt' else 'clear')

# now, to clear the screen
cls()

回答 2

好吧,这是一个快速的技巧:

>>> clear = "\n" * 100
>>> print clear
>>> ...do some other stuff...
>>> print clear

或保存一些输入,将此文件放在您的python搜索路径中:

# wiper.py
class Wipe(object):
    def __repr__(self):
        return '\n'*1000

wipe = Wipe()

然后,您就可以从解释器中进行所有操作:)

>>> from wiper import wipe
>>> wipe
>>> wipe
>>> wipe

Well, here’s a quick hack:

>>> clear = "\n" * 100
>>> print clear
>>> ...do some other stuff...
>>> print clear

Or to save some typing, put this file in your python search path:

# wiper.py
class Wipe(object):
    def __repr__(self):
        return '\n'*1000

wipe = Wipe()

Then you can do this from the interpreter all you like :)

>>> from wiper import wipe
>>> wipe
>>> wipe
>>> wipe

回答 3

尽管这是一个比较老的问题,但我认为我会提供一些建议,总结我认为是其他最佳答案的建议,并建议您将这些命令放入文件并设置PYTHONSTARTUP,以增加我的见识。环境变量指向它。由于我目前在Windows上,因此这种方式略有偏差,但很容易将其向其他方向倾斜。

我发现这里有一些文章描述了如何在Windows上设置环境变量:
    什么时候使用sys.path.append以及何时修改%PYTHONPATH%就足够了
    如何在Windows XP中管理环境变量
    配置系统和用户环境变量
    如何使用全局系统Windows中的环境变量

顺便说一句,即使文件中有空格,也不要在文件的路径两边加上引号。

无论如何,这是我放入(或添加到现有的)Python启动脚本中的代码的看法:

# ==== pythonstartup.py ====

# add something to clear the screen
class cls(object):
    def __repr__(self):
        import os
        os.system('cls' if os.name == 'nt' else 'clear')
        return ''

cls = cls()

# ==== end pythonstartup.py ====

顺便说一句,您也可以使用@ Triptych的 __repr__技巧将其更改exit()为just exit(别名也同上quit):

class exit(object):
    exit = exit # original object
    def __repr__(self):
        self.exit() # call original
        return ''

quit = exit = exit()

最后,这是将主解释程序提示从更改>>>cwd +的其他方法>>>

class Prompt:
    def __str__(self):
        import os
        return '%s >>> ' % os.getcwd()

import sys
sys.ps1 = Prompt()
del sys
del Prompt

Although this is an older question, I thought I’d contribute something summing up what I think were the best of the other answers and add a wrinkle of my own by suggesting that you put these command(s) into a file and set your PYTHONSTARTUP environment variable to point to it. Since I’m on Windows at the moment, it’s slightly biased that way, but could easily be slanted some other direction.

Here’s some articles I found that describe how to set environment variables on Windows:
    When to use sys.path.append and when modifying %PYTHONPATH% is enough
    How To Manage Environment Variables in Windows XP
    Configuring System and User Environment Variables
    How to Use Global System Environment Variables in Windows

BTW, don’t put quotes around the path to the file even if it has spaces in it.

Anyway, here’s my take on the code to put in (or add to your existing) Python startup script:

# ==== pythonstartup.py ====

# add something to clear the screen
class cls(object):
    def __repr__(self):
        import os
        os.system('cls' if os.name == 'nt' else 'clear')
        return ''

cls = cls()

# ==== end pythonstartup.py ====

BTW, you can also use @Triptych’s __repr__ trick to change exit() into just exit (and ditto for its alias quit):

class exit(object):
    exit = exit # original object
    def __repr__(self):
        self.exit() # call original
        return ''

quit = exit = exit()

Lastly, here’s something else that changes the primary interpreter prompt from >>> to cwd+>>>:

class Prompt:
    def __str__(self):
        import os
        return '%s >>> ' % os.getcwd()

import sys
sys.ps1 = Prompt()
del sys
del Prompt

回答 4

在Windows上,您可以采用多种方法:

1.使用键盘快捷键:

Press CTRL + L

2.使用系统调用方法:

import os
cls = lambda: os.system('cls')
cls()

3.使用换行打印100次:

cls = lambda: print('\n'*100)
cls()

You have number of ways doing it on Windows:

1. Using Keyboard shortcut:

Press CTRL + L

2. Using system invoke method:

import os
cls = lambda: os.system('cls')
cls()

3. Using new line print 100 times:

cls = lambda: print('\n'*100)
cls()

回答 5

毫无疑问,最快,最简单的方法是Ctrl+ L

对于终端上的OS X,这是相同的。

Quickest and easiest way without a doubt is Ctrl+L.

This is the same for OS X on the terminal.


回答 6

我这样做的方法是编写一个像这样的函数:

import os
import subprocess

def clear():
    if os.name in ('nt','dos'):
        subprocess.call("cls")
    elif os.name in ('linux','osx','posix'):
        subprocess.call("clear")
    else:
        print("\n") * 120

然后调用clear()以清除屏幕。这适用于Windows,OSX,Linux,BSD …所有操作系统。

my way of doing this is to write a function like so:

import os
import subprocess

def clear():
    if os.name in ('nt','dos'):
        subprocess.call("cls")
    elif os.name in ('linux','osx','posix'):
        subprocess.call("clear")
    else:
        print("\n") * 120

then call clear() to clear the screen. this works on windows, osx, linux, bsd… all OSes.


回答 7

这是一个跨平台(Windows / Linux / Mac /可能还可以在if检查中添加的跨平台)版本代码,我结合了在此问题中找到的信息制作而成:

import os
clear = lambda: os.system('cls' if os.name=='nt' else 'clear')
clear()

相同的想法,但用一勺语法糖:

import subprocess   
clear = lambda: subprocess.call('cls||clear', shell=True)
clear()

Here’s a cross platform (Windows / Linux / Mac / Probably others that you can add in the if check) version snippet I made combining information found in this question:

import os
clear = lambda: os.system('cls' if os.name=='nt' else 'clear')
clear()

Same idea but with a spoon of syntactic sugar:

import subprocess   
clear = lambda: subprocess.call('cls||clear', shell=True)
clear()

回答 8

刮水器很酷,关于它的好处是我不必在其周围键入’()’。这是它的细微变化

# wiper.py
import os
class Cls(object):
    def __repr__(self):
        os.system('cls')
        return ''

用法很简单:

>>> cls = Cls()
>>> cls # this will clear console.

Wiper is cool, good thing about it is I don’t have to type ‘()’ around it. Here is slight variation to it

# wiper.py
import os
class Cls(object):
    def __repr__(self):
        os.system('cls')
        return ''

The usage is quite simple:

>>> cls = Cls()
>>> cls # this will clear console.

回答 9

这是您可以做的最简单的事情,不需要任何其他库。它将清除屏幕并返回>>>到左上角。

print("\033[H\033[J")

This is the simplest thing you can do and it doesn’t require any additional libraries. It will clear the screen and return >>> to the top left corner.

print("\033[H\033[J")

回答 10

对于python控制台类型内的mac用户

import os
os.system('clear')

用于窗户

os.system('cls')

for the mac user inside the python console type

import os
os.system('clear')

for windows

os.system('cls')

回答 11

这是合并所有其他答案的最终解决方案。特征:

  1. 您可以代码复制粘贴到您的shell或脚本中。
  2. 您可以根据需要使用它:

    >>> clear()
    >>> -clear
    >>> clear  # <- but this will only work on a shell
  3. 您可以其作为模块导入

    >>> from clear import clear
    >>> -clear
  4. 您可以其称为脚本:

    $ python clear.py
  5. 它是真正的多平台 ; 如果它不能识别系统
    centdosposix)将回落到打印空白行。


您可以在此处下载[full]文件:https//gist.github.com/3130325
或如果您只是在寻找代码:

class clear:
 def __call__(self):
  import os
  if os.name==('ce','nt','dos'): os.system('cls')
  elif os.name=='posix': os.system('clear')
  else: print('\n'*120)
 def __neg__(self): self()
 def __repr__(self):
  self();return ''

clear=clear()

Here’s the definitive solution that merges all other answers. Features:

  1. You can copy-paste the code into your shell or script.
  2. You can use it as you like:

    >>> clear()
    >>> -clear
    >>> clear  # <- but this will only work on a shell
    
  3. You can import it as a module:

    >>> from clear import clear
    >>> -clear
    
  4. You can call it as a script:

    $ python clear.py
    
  5. It is truly multiplatform; if it can’t recognize your system
    (ce, nt, dos or posix) it will fall back to printing blank lines.


You can download the [full] file here: https://gist.github.com/3130325
Or if you are just looking for the code:

class clear:
 def __call__(self):
  import os
  if os.name==('ce','nt','dos'): os.system('cls')
  elif os.name=='posix': os.system('clear')
  else: print('\n'*120)
 def __neg__(self): self()
 def __repr__(self):
  self();return ''

clear=clear()

回答 12

我使用iTerm和Mac OS的本机终端应用程序。

我只要按⌘+ k

I use iTerm and the native terminal app for Mac OS.

I just press ⌘ + k


回答 13

使用空闲。它具有许多方便的功能。 Ctrl+F6,例如,重置控制台。关闭和打开控制台是清除它的好方法。

Use idle. It has many handy features. Ctrl+F6, for example, resets the console. Closing and opening the console are good ways to clear it.


回答 14

我不确定Windows的“ shell”是否支持此功能,但是在Linux上:

print "\033[2J"

https://zh.wikipedia.org/wiki/ANSI_escape_code#CSI_codes

在我看来,cls与通话os通常是一个坏主意。想象一下,如果我设法更改系统上的cls或clear命令,并且您以admin或root身份运行脚本。

I’m not sure if Windows’ “shell” supports this, but on Linux:

print "\033[2J"

https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_codes

In my opinion calling cls with os is a bad idea generally. Imagine if I manage to change the cls or clear command on your system, and you run your script as admin or root.


回答 15

我在Windows XP SP3上使用MINGW / BASH。

(在.pythonstartup坚持这一点)
#我CTRL-L已经样的工作,但是这可能帮助别人
#树叶窗口虽然…的底部提示
导入的ReadLine
readline.parse_and_bind(“氯\:清屏”)

#这在BASH中有效,因为我也在.inputrc中也有它,但是由于某些
原因,当我进入Python
readline 时它被丢弃了(’\ Cy:kill-whole-line’)


我再也无法忍受键入’exit()’了,对martineau / Triptych的把戏感到满意:

我虽然稍加修改(将其粘贴在.pythonstartup中)

class exxxit():
    """Shortcut for exit() function, use 'x' now"""
    quit_now = exit # original object
    def __repr__(self):
        self.quit_now() # call original
x = exxxit()

Py2.7.1>help(x)
Help on instance of exxxit in module __main__:

class exxxit
 |  Shortcut for exit() function, use 'x' now
 |
 |  Methods defined here:
 |
 |  __repr__(self)
 |
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |
 |  quit_now = Use exit() or Ctrl-Z plus Return to exit

I’m using MINGW/BASH on Windows XP, SP3.

(stick this in .pythonstartup)
# My ctrl-l already kind of worked, but this might help someone else
# leaves prompt at bottom of the window though…
import readline
readline.parse_and_bind(‘\C-l: clear-screen’)

# This works in BASH because I have it in .inputrc as well, but for some
# reason it gets dropped when I go into Python
readline.parse_and_bind(‘\C-y: kill-whole-line’)


I couldn’t stand typing ‘exit()’ anymore and was delighted with martineau’s/Triptych’s tricks:

I slightly doctored it though (stuck it in .pythonstartup)

class exxxit():
    """Shortcut for exit() function, use 'x' now"""
    quit_now = exit # original object
    def __repr__(self):
        self.quit_now() # call original
x = exxxit()

Py2.7.1>help(x)
Help on instance of exxxit in module __main__:

class exxxit
 |  Shortcut for exit() function, use 'x' now
 |
 |  Methods defined here:
 |
 |  __repr__(self)
 |
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |
 |  quit_now = Use exit() or Ctrl-Z plus Return to exit

回答 16

clearLinux和clsWindows中的OS命令输出一个“魔术字符串”,您可以直接打印该字符串。要获取字符串,请使用popen执行命令并将其保存在变量中以备后用:

from os import popen
with popen('clear') as f:
    clear = f.read()

print clear

在我的机器上,字符串是'\x1b[H\x1b[2J'

The OS command clear in Linux and cls in Windows outputs a “magic string” which you can just print. To get the string, execute the command with popen and save it in a variable for later use:

from os import popen
with popen('clear') as f:
    clear = f.read()

print clear

On my machine the string is '\x1b[H\x1b[2J'.


回答 17

这是两种不错的方法:

1。

import os

# Clear Windows command prompt.
if (os.name in ('ce', 'nt', 'dos')):
    os.system('cls')

# Clear the Linux terminal.
elif ('posix' in os.name):
    os.system('clear')

2。

import os

def clear():
    if os.name == 'posix':
        os.system('clear')

    elif os.name in ('ce', 'nt', 'dos'):
        os.system('cls')


clear()

Here are two nice ways of doing that:

1.

import os

# Clear Windows command prompt.
if (os.name in ('ce', 'nt', 'dos')):
    os.system('cls')

# Clear the Linux terminal.
elif ('posix' in os.name):
    os.system('clear')

2.

import os

def clear():
    if os.name == 'posix':
        os.system('clear')

    elif os.name in ('ce', 'nt', 'dos'):
        os.system('cls')


clear()

回答 18

如果是在Mac上,那么一个简单的方法cmd + k就可以解决问题。

If it is on mac, then a simple cmd + k should do the trick.


回答 19

最简单的方法是使用os模块

>>> import os
>>> clear = lambda: os.system('clear')
>>> clear()

The easiest way is to use os module

>>> import os
>>> clear = lambda: os.system('clear')
>>> clear()

回答 20

这应该是跨平台的,并且还使用所述优选的subprocess.call,而不是os.systemos.system文档。应该适用于Python> = 2.4。

import subprocess
import os

if os.name == 'nt':
    def clearscreen():
        subprocess.call("cls", shell=True)
        return
else:
    def clearscreen():
        subprocess.call("clear", shell=True)
        return

This should be cross platform, and also uses the preferred subprocess.call instead of os.system as per the os.system docs. Should work in Python >= 2.4.

import subprocess
import os

if os.name == 'nt':
    def clearscreen():
        subprocess.call("cls", shell=True)
        return
else:
    def clearscreen():
        subprocess.call("clear", shell=True)
        return

回答 21

这样清楚吗

- os.system('cls')

那大约是尽可能的短!

How about this for a clear

- os.system('cls')

That is about as short as could be!


回答 22

我是python的新手(真的很新),在我读的一本书中,他们熟悉该语言,他们教他们如何创建此小功能来清除控制台的可见积压以及过去的命令和打印内容:

打开外壳程序/创建新文档/创建函数,如下所示:

def clear():
    print('\n' * 50)

将其保存在python目录中的lib文件夹中(我的文件夹为C:\ Python33 \ Lib)。下次您需要清除控制台时,只需使用以下函数调用该函数:

clear()

而已。PS:您可以随意命名自己的功能。我见过人们使用“雨刮器”,“擦拭”和其他形式。

I’m new to python (really really new) and in one of the books I’m reading to get acquainted with the language they teach how to create this little function to clear the console of the visible backlog and past commands and prints:

Open shell / Create new document / Create function as follows:

def clear():
    print('\n' * 50)

Save it inside the lib folder in you python directory (mine is C:\Python33\Lib) Next time you nedd to clear your console just call the function with:

clear()

that’s it. PS: you can name you function anyway you want. Iv’ seen people using “wiper” “wipe” and variations.


回答 23

我正在使用Spyder(Python 2.7),并且要清洁解释器控制台,请使用

%明确

迫使命令行转到顶部,而我不会看到以前的旧命令。

或在控制台环境中单击“选项”,然后选择“ Restart kernel”(删除所有内容)。

I am using Spyder (Python 2.7) and to clean the interpreter console I use either

%clear

that forces the command line to go to the top and I will not see the previous old commands.

or I click “option” on the Console environment and select “Restart kernel” that removes everything.


回答 24

我可能迟到了,但这是一个很简单的方法

类型:

def cls():
    os.system("cls")

所以只要您想输入清除代码的内容

cls()

最好的方法!(信用:https : //www.youtube.com/watch?annotation_id=annotation_3770292585&feature=iv&src_vid=bguKhMnvmb8&v=LtGEp9c6Z-U

I might be late to the part but here is a very easy way to do it

Type:

def cls():
    os.system("cls")

So what ever you want to clear the screen just type in your code

cls()

Best way possible! (Credit : https://www.youtube.com/watch?annotation_id=annotation_3770292585&feature=iv&src_vid=bguKhMnvmb8&v=LtGEp9c6Z-U)


回答 25

只需输入

import os
os.system('cls') # Windows
os.system('clear') # Linux, Unix, Mac OS X

Just enter

import os
os.system('cls') # Windows
os.system('clear') # Linux, Unix, Mac OS X

回答 26

如果您不需要通过代码完成操作,只需按CTRL + L

If you don’t need to do it through code, just press CTRL+L


回答 27

Arch Linux(已在xfce4-terminalPython 3中测试):

# Clear or wipe console (terminal):
# Use: clear() or wipe()

import os

def clear():
    os.system('clear')

def wipe():
    os.system("clear && printf '\e[3J'")

… 添加到 ~/.pythonrc

  • clear() 清除屏幕
  • wipe() 擦除整个终端缓冲区

Arch Linux (tested in xfce4-terminal with Python 3):

# Clear or wipe console (terminal):
# Use: clear() or wipe()

import os

def clear():
    os.system('clear')

def wipe():
    os.system("clear && printf '\e[3J'")

… added to ~/.pythonrc

  • clear() clears screen
  • wipe() wipes entire terminal buffer

回答 28

编辑:我刚刚读过“ Windows”,这是给Linux用户的,抱歉。


在bash中:

#!/bin/bash

while [ "0" == "0" ]; do
    clear
    $@
    while [ "$input" == "" ]; do
        read -p "Do you want to quit? (y/n): " -n 1 -e input
        if [ "$input" == "y" ]; then
            exit 1
        elif [ "$input" == "n" ]; then
            echo "Ok, keep working ;)"
        fi
    done
    input=""
done

将其保存为“ whatyouwant.sh”,chmod + x然后运行:

./whatyouwant.sh python

或python以外的其他东西(空闲等)。这将询问您是否确实要退出,如果不是,则重新运行python(或您作为参数给出的命令)。

这将清除所有,屏幕以及您在python中创建/导入的所有变量/对象/所有内容。

在python中,当您要退出时只需键入exit()即可。

EDIT: I’ve just read “windows”, this is for linux users, sorry.


In bash:

#!/bin/bash

while [ "0" == "0" ]; do
    clear
    $@
    while [ "$input" == "" ]; do
        read -p "Do you want to quit? (y/n): " -n 1 -e input
        if [ "$input" == "y" ]; then
            exit 1
        elif [ "$input" == "n" ]; then
            echo "Ok, keep working ;)"
        fi
    done
    input=""
done

Save it as “whatyouwant.sh”, chmod +x it then run:

./whatyouwant.sh python

or something other than python (idle, whatever). This will ask you if you actually want to exit, if not it rerun python (or the command you gave as parameter).

This will clear all, the screen and all the variables/object/anything you created/imported in python.

In python just type exit() when you want to exit.


回答 29

好的,所以这是一个技术性较差的答案,但是我使用的是Notepad ++的Python插件,事实证明,您可以通过右键单击控制台并单击“清除”来手动清除控制台。希望这可以帮助某人!

OK, so this is a much less technical answer, but I’m using the Python plugin for Notepad++ and it turns out you can just clear the console manually by right-clicking on it and clicking “clear”. Hope this helps someone out there!


在Python中以YYYY-MM-DD获取今天的日期?

问题:在Python中以YYYY-MM-DD获取今天的日期?

我在用着:

str(datetime.datetime.today()).split()[0]

YYYY-MM-DD格式返回今天的日期。

有没有那么简单的方法可以做到这一点?

I’m using:

str(datetime.datetime.today()).split()[0]

to return today’s date in the YYYY-MM-DD format.

Is there a less crude way to achieve this?


回答 0

您可以使用strftime

from datetime import datetime

datetime.today().strftime('%Y-%m-%d')

此外,对于任何还在末尾寻找零填充的小时,分​​钟和秒的人:(Gabriel Staples评论)

datetime.today().strftime('%Y-%m-%d-%H:%M:%S')

You can use strftime:

from datetime import datetime

datetime.today().strftime('%Y-%m-%d')

Additionally, for anyone also looking for a zero-padded Hour, Minute, and Second at the end: (Comment by Gabriel Staples)

datetime.today().strftime('%Y-%m-%d-%H:%M:%S')

回答 1

您可以使用datetime.date.today()并将结果datetime.date对象转换为字符串:

from datetime import date
today = str(date.today())
print(today)   # '2017-12-26'

You can use datetime.date.today() and convert the resulting datetime.date object to a string:

from datetime import date
today = str(date.today())
print(today)   # '2017-12-26'

回答 2

如果您想记住有趣的代码,那么日期时间就是很好的选择。您不喜欢简单吗?

>>> import arrow
>>> arrow.now().format('YYYY-MM-DD')
'2017-02-17'

这个模块足够聪明,可以理解您的意思

做吧pip install arrow

附录:在回答那些对此练习感到困惑的人时,我只想说箭头代表了Python处理日期的另一种方法。这主要是我的建议。

Datetime is just lovely if you like remembering funny codes. Wouldn’t you prefer simplicity?

>>> import arrow
>>> arrow.now().format('YYYY-MM-DD')
'2017-02-17'

This module is clever enough to understand what you mean.

Just do pip install arrow.

Addendum: In answer to those who become exercised over this answer let me just say that arrow represents one of the alternative approaches to dealing with dates in Python. That’s mostly what I meant to suggest.


回答 3

我总是isoformat()为此使用功能。

from datetime import date    
today = date.today().isoformat()
print(today) # '2018-12-05'

请注意,如果您还需要标准格式的时间,则此方法也适用于datetime对象。

from datetime import datetime
now = datetime.today().isoformat()
print(now) # '2018-12-05T11:15:55.126382'

I always use the isoformat() function for this.

from datetime import date    
today = date.today().isoformat()
print(today) # '2018-12-05'

Note that this also works on datetime objects if you need the time in standard format as well.

from datetime import datetime
now = datetime.today().isoformat()
print(now) # '2018-12-05T11:15:55.126382'

回答 4

其他答案建议使用python datetime.datetime,但是正如@Bill Bell所说,还有其他库提供了更简单的datetime接口,这些接口既可以作为服务,也可以作为更大的API生态系统的一部分。这里有两个这样的库使工作变得datetimes非常简单。

潘达斯

您可以pd.to_datetimepandas库中使用。这里有各种选项,具体取决于您要返回的内容。

import pandas as pd

pd.to_datetime('today')  # pd.to_datetime('now')
# Timestamp('2019-03-27 00:00:10.958567')

作为python datetime对象,

pd.to_datetime('today').to_pydatetime()
# datetime.datetime(2019, 4, 18, 3, 50, 42, 587629)

作为格式化的日期字符串,

pd.to_datetime('today').isoformat()
# '2019-04-18T04:03:32.493337'

# Or, `strftime` for custom formats.
pd.to_datetime('today').strftime('%Y-%m-%d')
# '2019-03-27'

要仅从时间戳记中获取日期,请调用Timestamp.date

pd.to_datetime('today').date()
# datetime.date(2019, 3, 27)

除了之外to_datetime,您还可以Timestamp使用实例化对象,

pd.Timestamp('today')  # pd.Timestamp('now')
# Timestamp('2019-04-18 03:43:33.233093')

pd.Timestamp('today').to_pydatetime()
# datetime.datetime(2019, 4, 18, 3, 53, 46, 220068)

如果要使您的时间戳记时区知道,请将时区传递给tz参数。

pd.Timestamp('now', tz='America/Los_Angeles')
# Timestamp('2019-04-18 03:59:02.647819-0700', tz='America/Los_Angeles')

如果您使用摆锤,则有一些有趣的选择。您可以使用来获取当前时间戳记now()或使用来获取今天的日期today()

import pendulum 

pendulum.now()
# DateTime(2019, 3, 27, 0, 2, 41, 452264, tzinfo=Timezone('America/Los_Angeles'))

pendulum.today()
# DateTime(2019, 3, 27, 0, 0, 0, tzinfo=Timezone('America/Los_Angeles'))

此外,您也可以直接获取tomorrow()yesterday()的日期,而无需执行任何其他的timedelta算法。

pendulum.yesterday()
# DateTime(2019, 3, 26, 0, 0, 0, tzinfo=Timezone('America/Los_Angeles'))

pendulum.tomorrow()
# DateTime(2019, 3, 28, 0, 0, 0, tzinfo=Timezone('America/Los_Angeles'))

有各种可用的格式设置选项。

pendulum.now().to_date_string()
# '2019-03-27'

pendulum.now().to_formatted_date_string()
# 'Mar 27, 2019'

pendulum.now().to_day_datetime_string()
# 'Wed, Mar 27, 2019 12:04 AM'

Other answers suggest the use of python’s datetime.datetime, but as @Bill Bell said, there are other libraries that offer simpler datetime interfaces either as a service or as part of a larger ecosystem of APIs. Here are two such libraries that make working with datetimes very simple.

PANDAS

You can use pd.to_datetime from the pandas library. Here are various options, depending on what you want returned.

import pandas as pd

pd.to_datetime('today')  # pd.to_datetime('now')
# Timestamp('2019-03-27 00:00:10.958567')

As a python datetime object,

pd.to_datetime('today').to_pydatetime()
# datetime.datetime(2019, 4, 18, 3, 50, 42, 587629)

As a formatted date string,

pd.to_datetime('today').isoformat()
# '2019-04-18T04:03:32.493337'

# Or, `strftime` for custom formats.
pd.to_datetime('today').strftime('%Y-%m-%d')
# '2019-03-27'

To get just the date from the timestamp, call Timestamp.date.

pd.to_datetime('today').date()
# datetime.date(2019, 3, 27)

Aside from to_datetime, you can directly instantiate a Timestamp object using,

pd.Timestamp('today')  # pd.Timestamp('now')
# Timestamp('2019-04-18 03:43:33.233093')

pd.Timestamp('today').to_pydatetime()
# datetime.datetime(2019, 4, 18, 3, 53, 46, 220068)

If you want to make your Timestamp timezone aware, pass a timezone to the tz argument.

pd.Timestamp('now', tz='America/Los_Angeles')
# Timestamp('2019-04-18 03:59:02.647819-0700', tz='America/Los_Angeles')

PENDULUM

If you’re working with pendulum, there are some interesting choices. You can get the current timestamp using now() or today’s date using today().

import pendulum 

pendulum.now()
# DateTime(2019, 3, 27, 0, 2, 41, 452264, tzinfo=Timezone('America/Los_Angeles'))

pendulum.today()
# DateTime(2019, 3, 27, 0, 0, 0, tzinfo=Timezone('America/Los_Angeles'))

Additionally, you can also get tomorrow() or yesterday()‘s date directly without having to do any additional timedelta arithmetic.

pendulum.yesterday()
# DateTime(2019, 3, 26, 0, 0, 0, tzinfo=Timezone('America/Los_Angeles'))

pendulum.tomorrow()
# DateTime(2019, 3, 28, 0, 0, 0, tzinfo=Timezone('America/Los_Angeles'))

There are various formatting options available.

pendulum.now().to_date_string()
# '2019-03-27'

pendulum.now().to_formatted_date_string()
# 'Mar 27, 2019'

pendulum.now().to_day_datetime_string()
# 'Wed, Mar 27, 2019 12:04 AM'

回答 5

答案很晚,但是您可以使用:

import time
today = time.strftime("%Y-%m-%d")
# 2020-02-14

Very late answer, but you can use:

import time
today = time.strftime("%Y-%m-%d")
# 2020-02-14

回答 6

您可以使用,

>>> from datetime import date
>>> date.today().__str__()
'2019-10-05'

You can use,

>>> from datetime import date
>>> date.today().__str__()
'2019-10-05'

回答 7

我喜欢这个,因为这很简单,但是可能效率不高且有问题。如果您要一个高度防错的程序,则必须检查shell命令的退出代码。

os.system('date +%Y-%m-%d')

I prefer this, because this is simple, but maybe somehow inefficient and buggy. You must check the exit code of shell command if you want a strongly error-proof program.

os.system('date +%Y-%m-%d')

为什么Python对于函数式编程不是很好?[关闭]

问题:为什么Python对于函数式编程不是很好?[关闭]

我一直认为函数式编程可以在Python中完成。因此,令我感到惊讶的是,Python在这个问题上没有得到太多提及,而当提及它时,通常不是很积极。但是,没有给出太多的原因(缺少模式匹配和代数数据类型)。所以我的问题是:为什么Python对于函数式编程不是很好?除了缺乏模式匹配和代数数据类型之外,还有其他原因吗?还是这些概念对函数式编程如此重要,以致于不支持它们的语言只能被归类为一流的函数式编程语言?(请记住,我在函数式编程方面的经验非常有限。)

I have always thought that functional programming can be done in Python. Thus, I was surprised that Python didn’t get much of a mention in this question, and when it was mentioned, it normally wasn’t very positive. However, not many reasons were given for this (lack of pattern matching and algebraic data types were mentioned). So my question is: why isn’t Python very good for functional programming? Are there more reasons than its lack of pattern matching and algebraic data types? Or are these concepts so important to functional programming that a language that doesn’t support them can only be classed as a second rate functional programming language? (Keep in mind that my experience with functional programming is quite limited.)


回答 0

您所参考的问题将询问哪些语言同时促进OO和功能编程。即使Python 运作良好,它也不会促进函数式编程。

反对 Python 中的函数式编程的最佳论据是Guido仔细考虑了命令式/ OO用例,而函数式编程用例则没有。当我编写命令式Python时,它是我所知道的最漂亮的语言之一。当我编写函数式Python时,它变得和没有BDFL的普通语言一样丑陋和令人不快。

这并不是说这很糟糕,只是您必须比您改用促进功能编程的语言或改用编写OO Python的语言更加努力。

以下是我在Python中缺少的功能:


  • 没有模式匹配,也没有尾递归,这意味着必须强制性地编写基本算法。递归在Python中很丑陋而且很慢。
  • 一个小的列表库,没有功能词典,这意味着您必须自己编写很多东西。
  • 没有用于currying或composition的语法,这意味着无点样式几乎像显式传递参数一样充满标点符号。
  • 迭代器而不是惰性列表意味着您必须知道是要效率还是持久性,并且list如果需要持久性,则需要分散调用。(迭代器只能使用一次)
  • Python的简单命令式语法及其简单的LL1解析器意味着,基本上不可能为if-expressions和lambda-expressions提供更好的语法。Guido喜欢这种方式,我认为他是对的。

The question you reference asks which languages promote both OO and functional programming. Python does not promote functional programming even though it works fairly well.

The best argument against functional programming in Python is that imperative/OO use cases are carefully considered by Guido, while functional programming use cases are not. When I write imperative Python, it’s one of the prettiest languages I know. When I write functional Python, it becomes as ugly and unpleasant as your average language that doesn’t have a BDFL.

Which is not to say that it’s bad, just that you have to work harder than you would if you switched to a language that promotes functional programming or switched to writing OO Python.

Here are the functional things I miss in Python:


  • No pattern matching and no tail recursion mean your basic algorithms have to be written imperatively. Recursion is ugly and slow in Python.
  • A small list library and no functional dictionaries mean that you have to write a lot of stuff yourself.
  • No syntax for currying or composition means that point-free style is about as full of punctuation as explicitly passing arguments.
  • Iterators instead of lazy lists means that you have to know whether you want efficiency or persistence, and to scatter calls to list around if you want persistence. (Iterators are use-once)
  • Python’s simple imperative syntax, along with its simple LL1 parser, mean that a better syntax for if-expressions and lambda-expressions is basically impossible. Guido likes it this way, and I think he’s right.

回答 1

Guido 在这里对此有很好的解释。这是最相关的部分:

我从来没有考虑过Python受功能语言的严重影响,无论人们怎么说。我对诸如C和Algol 68之类的命令式语言更加熟悉,尽管我使函数成为一流的对象,但我并不认为Python是一种函数式编程语言。但是,很早以前,很明显,用户希望对列表和函数做更多的事情。

还值得注意的是,即使我没有将Python设想为一种功能语言,闭包的引入对于许多其他高级编程功能的开发也很有用。例如,新型类,装饰器和其他现代功能的某些方面都依赖此功能。

最后,尽管这些年来已经引入了许多功能编程功能,但是Python仍然缺少“真实”功能编程语言中的某些功能。例如,Python不执行某些类型的优化(例如,尾部递归)。通常,由于Python具有极强的动态特性,因此无法进行从Haskell或ML之类的功能语言中已知的那种编译时优化。很好。

我从中得出两点:

  1. 该语言的创建者并没有真正将Python视为一种功能语言。因此,有可能看到“功能式”功能,但是您不太可能看到任何确定的功能。
  2. Python的动态特性抑制了您在其他功能语言中看到的某些优化。诚然,Lisp与Python一样动态(如果不是更动态的话),因此这只是部分解释。

Guido has a good explanation of this here. Here’s the most relevant part:

I have never considered Python to be heavily influenced by functional languages, no matter what people say or think. I was much more familiar with imperative languages such as C and Algol 68 and although I had made functions first-class objects, I didn’t view Python as a functional programming language. However, earlier on, it was clear that users wanted to do much more with lists and functions.

It is also worth noting that even though I didn’t envision Python as a functional language, the introduction of closures has been useful in the development of many other advanced programming features. For example, certain aspects of new-style classes, decorators, and other modern features rely upon this capability.

Lastly, even though a number of functional programming features have been introduced over the years, Python still lacks certain features found in “real” functional programming languages. For instance, Python does not perform certain kinds of optimizations (e.g., tail recursion). In general, because Python’s extremely dynamic nature, it is impossible to do the kind of compile-time optimization known from functional languages like Haskell or ML. And that’s fine.

I pull two things out of this:

  1. The language’s creator doesn’t really consider Python to be a functional language. Therefore, it’s possible to see “functional-esque” features, but you’re unlikely to see anything that is definitively functional.
  2. Python’s dynamic nature inhibits some of the optimizations you see in other functional languages. Granted, Lisp is just as dynamic (if not more dynamic) as Python, so this is only a partial explanation.

回答 2

Scheme没有代数数据类型或模式匹配,但肯定是一种功能语言。从功能编程的角度来看,有关Python的烦人的事情:

  1. 残缺的Lambdas。由于Lambda仅包含一个表达式,并且您无法在表达式上下文中轻松地进行所有操作,因此这意味着您可以“即时”定义的功能受到限制。

  2. 如果是语句,而不是表达式。这意味着,除其他事项外,您不能在其中带有If的lambda。(这在Python 2.5中由三元数修复,但看起来很丑。)

  3. 圭多威胁要删除地图,过滤器,并减少在每过一段时间

另一方面,python具有词汇闭包,Lambda和列表理解(无论Guido是否接受,这实际上都是“功能性”概念)。我在Python中进行了大量的“函数式”编程,但是我很难说它是理想的。

Scheme doesn’t have algebraic data types or pattern matching but it’s certainly a functional language. Annoying things about Python from a functional programming perspective:

  1. Crippled Lambdas. Since Lambdas can only contain an expression, and you can’t do everything as easily in an expression context, this means that the functions you can define “on the fly” are limited.

  2. Ifs are statements, not expressions. This means, among other things, you can’t have a lambda with an If inside it. (This is fixed by ternaries in Python 2.5, but it looks ugly.)

  3. Guido threatens to remove map, filter, and reduce every once in a while

On the other hand, python has lexical closures, Lambdas, and list comprehensions (which are really a “functional” concept whether or not Guido admits it). I do plenty of “functional-style” programming in Python, but I’d hardly say it’s ideal.


回答 3

我永远都不会将Python称为“功能性的”,但每当我使用Python进行编程时,代码总是以几乎纯粹的功能性结尾。

诚然,这主要是由于列表理解非常好。因此,我不一定会建议将Python作为一种功能编程语言,但我建议对使用Python的任何人进行功能编程。

I would never call Python “functional” but whenever I program in Python the code invariably ends up being almost purely functional.

Admittedly, that’s mainly due to the extremely nice list comprehension. So I wouldn’t necessarily suggest Python as a functional programming language but I would suggest functional programming for anyone using Python.


回答 4

让我用从SO上的“功能性” Python问题的答案中摘录的一段代码来演示

Python:

def grandKids(generation, kidsFunc, val):
  layer = [val]
  for i in xrange(generation):
    layer = itertools.chain.from_iterable(itertools.imap(kidsFunc, layer))
  return layer

Haskell:

grandKids generation kidsFunc val =
  iterate (concatMap kidsFunc) [val] !! generation

这里的主要区别是,Haskell的标准库中有函数式编程有用的功能:在这种情况下iterateconcat(!!)

Let me demonstrate with a piece of code taken from an answer to a “functional” Python question on SO

Python:

def grandKids(generation, kidsFunc, val):
  layer = [val]
  for i in xrange(generation):
    layer = itertools.chain.from_iterable(itertools.imap(kidsFunc, layer))
  return layer

Haskell:

grandKids generation kidsFunc val =
  iterate (concatMap kidsFunc) [val] !! generation

The main difference here is that Haskell’s standard library has useful functions for functional programming: in this case iterate, concat, and (!!)


回答 5

对于这个问题(和答案)而言,真正重要的一件事是:函数式编程到底是什么,它的最重要特性是什么。我将尽我的看法:

函数式编程很像在白板上写数学。在白板上写方程式时,您无需考虑执行顺序。(通常)没有突变。您不会在第二天回来查看它,并且当您再次进行计算时,您会得到不同的结果(或者,如果您喝了一些新鲜的咖啡,则可以:)。基本上,板子上有什么,当您开始写下内容时,答案已经在那里,您只是还没有意识到它到底是什么。

函数式编程非常像这样。您不会改变任何事情,只需评估方程式(在本例中为“程序”),然后找出答案是什么。该程序仍然存在,未经修改。与数据相同。

我将以下内容列为函数式编程的最重要特征:a)引用透明性-如果您在其他时间和地点评估相同的语句,但具有相同的变量值,则其含义仍相同。b)没有副作用-不管您凝视白板多长时间,另一个人看着另一个白板的方程式都不会意外改变。c)函数也是值。可以传递给其他变量或与其他变量一起应用。d)函数组合,您可以执行h = g·f,从而定义一个新函数h(..),该函数等效于调用g(f(..))。

此列表按我的优先顺序排列,因此参照透明性是最重要的,其次没有副作用。

现在,如果您通过python检查语言和库在这些方面的支持和保证程度,那么您就可以很好地回答自己的问题了。

One thing that is really important for this question (and the answers) is the following: What the hell is functional programming, and what are the most important properties of it. I’ll try to give my view of it:

Functional programming is a lot like writing math on a whiteboard. When you write equations on a whiteboard, you do not think about an execution order. There is (typically) no mutation. You don’t come back the day after and look at it, and when you make the calculations again, you get a different result (or you may, if you’ve had some fresh coffee :)). Basically, what is on the board is there, and the answer was already there when you started writing things down, you just haven’t realized what it is yet.

Functional programming is a lot like that; you don’t change things, you just evaluate the equation (or in this case, “program”) and figure out what the answer is. The program is still there, unmodified. The same with the data.

I would rank the following as the most important features of functional programming: a) referential transparency – if you evaluate the same statement at some other time and place, but with the same variable values, it will still mean the same. b) no side effect – no matter how long you stare at the whiteboard, the equation another guy is looking at at another whiteboard won’t accidentally change. c) functions are values too. which can be passed around and applied with, or to, other variables. d) function composition, you can do h=g·f and thus define a new function h(..) which is equivalent to calling g(f(..)).

This list is in my prioritized order, so referential transparency is the most important, followed by no side effects.

Now, if you go through python and check how well the language and libraries supports, and guarantees, these aspects – then you are well on the way to answer your own question.


回答 6

Python几乎是一种功能语言。这是“功能精简版”。

它具有额外的功能,因此对于某些人来说还不够纯粹。

它还缺少一些功能,因此对于某些功能来说还不够完善。

缺少的功能相对容易编写。在Python中的FP上查看此类帖子。

Python is almost a functional language. It’s “functional lite”.

It has extra features, so it isn’t pure enough for some.

It also lacks some features, so it isn’t complete enough for some.

The missing features are relatively easy to write. Check out posts like this on FP in Python.


回答 7

上面未提及的另一个原因是,许多内置类型的内置函数和方法会修改对象,但不会返回修改后的对象。如果返回那些修改后的对象,那将使功能代码更简洁。例如,如果some_list.append(some_object)返回添加了some_object的some_list。

Another reason not mentioned above is that many built-in functions and methods of built-in types modify an object but do not return the modified object. If those modified objects were returned, that would make functional code cleaner and more concise. For example, if some_list.append(some_object) returned some_list with some_object appended.


回答 8

除了其他答案外,Python和大多数其他多范式语言不太适合真正的函数式编程的一个原因是,因为它们的编译器/虚拟机/运行时不支持函数优化。通过编译器理解数学规则可以实现这种优化。例如,许多编程语言都支持map函数或方法。这是一个相当标准的函数,该函数将一个函数作为一个参数,将一个Iterable作为第二个参数,然后将该函数应用于Iterable中的每个元素。

无论如何,结果map( foo() , x ) * map( foo(), y )与相同map( foo(), x * y )。后者的情况实际上比前者快,因为前者执行两份副本,后者执行一份。

更好的功能语言会识别这些基于数学的关系并自动执行优化。非专用于功能范例的语言可能不会进行优化。

In addition to other answers, one reason Python and most other multi-paradigm languages are not well suited for true functional programming is because their compilers / virtual machines / run-times do not support functional optimization. This sort of optimization is achieved by the compiler understanding mathematical rules. For example, many programming languages support a map function or method. This is a fairly standard function that takes a function as one argument and a iterable as the second argument then applies that function to each element in the iterable.

Anyways it turns out that map( foo() , x ) * map( foo(), y ) is the same as map( foo(), x * y ). The latter case is actually faster than the former because the former performs two copies where the latter performs one.

Better functional languages recognize these mathematically based relationships and automatically perform the optimization. Languages that aren’t dedicated to the functional paradigm will likely not optimize.


教初学者编程的最佳方法?[关闭]

问题:教初学者编程的最佳方法?[关闭]

原始问题

我目前正在教我的兄弟编程。他是一个初学者,但非常聪明。(他实际上想学习)。我注意到我们的某些会议在次要细节上陷入了停滞,而且我感觉自己组织得不够好。(但是这篇文章的答案很有帮助。

我可以做些什么更好地有效地教他?我可以用逻辑顺序来逐个概念地进行研究吗?我应该避免复杂到以后吗?

我们正在使用的语言是Python,但是欢迎提供任何语言的建议。


如何帮助

如果您有好的,请在答案中添加以下内容:

  • 初学者练习和项目构想
  • 教学初学者的资源
  • 截屏视频/博客文章/免费电子书
  • 打印适合初学者的书籍

通过链接描述资源以便我看看。我希望每个人都知道我肯定已经使用了其中一些想法。您的意见将汇总在此帖子中。


面向初学者的在线资源


推荐给初学者的印刷书籍

Original Question

I am currently engaged in teaching my brother to program. He is a total beginner, but very smart. (And he actually wants to learn). I’ve noticed that some of our sessions have gotten bogged down in minor details, and I don’t feel I’ve been very organized. (But the answers to this post have helped a lot.)

What can I do better to teach him effectively? Is there a logical order that I can use to run through concept by concept? Are there complexities I should avoid till later?

The language we are working with is Python, but advice in any language is welcome.


How to Help

If you have good ones please add the following in your answer:

  • Beginner Exercises and Project Ideas
  • Resources for teaching beginners
  • Screencasts / blog posts / free e-books
  • Print books that are good for beginners

Please describe the resource with a link to it so I can take a look. I want everyone to know that I have definitely been using some of these ideas. Your submissions will be aggregated in this post.


Online Resources for teaching beginners:


Recommended Print Books for teaching beginners


回答 0

我不得不和几个初学者(从来没有写过任何代码)程序员一起工作,今年秋天我将与高中生一起进行课后工作坊。这是我最接近文档的内容。这项工作仍在进行中,但希望对您有所帮助。

1)FizzBu​​zz。从命令行程序开始。您可以非常快速地编写一些有趣的游戏或工具,并且无需首先学习GUI工具即可非常快速地学习所有语言功能。这些早期的应用程序应该足够简单,您无需使用任何真正的调试工具即可使其运行。

如果没有别的,像FizzBu​​zz这样的项目都是好项目。您的前几个应用程序不必处理数据库,文件系统,配置等。这些概念使大多数人感到困惑,并且当您仅学习语法和基本框架功能时,您实际上并不需要更多的复杂性。

一些项目:

  • 你好,世界!
  • 以我的出生年份为基础,计算我的年龄(仅(现在-然后)没有月份修正)。(简单的数学,输入,输出)
  • 询问方向(上,下,左,右),然后告诉用户他们的命运(掉进洞里,找到蛋糕,等等)。(布尔逻辑)
  • FizzBu​​zz,但每秒计数一次。(循环,计时器和更多逻辑)
  • 根据他们的年龄,有些人真的很喜欢应用程序,该应用程序会在一定间隔内对用户进行随机侮辱。(如果将间隔设为随机,则循环,数组,计时器和随机)

2)简单项目一旦他们掌握了语言功能,就可以开始一个项目(简单,有趣的游戏效果很好。)。您应该尝试使第一个项目能够在6到12个小时内完成。不要花时间来架构它。让他们设计它,即使它很烂。如果失败了,请谈论发生的事情以及失败的原因,然后选择另一个主题并重新开始。

从这里开始介绍工具的调试功能。即使您通过阅读代码可以看到问题,也应该教他们如何使用工具,然后向他们展示如何看到它们。这具有教调试工具和教如何在没有工具的情况下识别错误的双重目的。

一旦项目开始运行,或者如果项目开始运行,则可以使用它来引入重构工具。如果您随后可以使用一些您从未计划过的简单功能来扩展项目,那就很好了。这通常意味着重构和大量的调试,因为很少有人会在第一次编写甚至一半不错的代码。

一些项目:

  • man子手游戏
  • 试验机器人(VexMindstorms是可选的)

3)真实项目开始一个实际项目可能需要一些时间。使用适当的源代码控制,并提出时间表。像实际项目一样运行此项目,如果没有其他必要的经验,则必须使用这些工具。

显然,您需要针对每个人进行调整。我发现的最重要的事情是,即使第一个简单的应用程序也可以应用于人们感兴趣的内容。

一些项目:

  • 俄罗斯方块
  • 基于文本文件的博客引擎
  • 更先进的机器人工作

I’ve had to work with several beginner (never wrote a line of code) programmers, and I’ll be doing an after school workshop with high school students this fall. This is the closest thing I’ve got to documentation. It’s still a work in progress, but I hope it helps.

1) FizzBuzz. Start with command line programs. You can write some fun games, or tools, very quickly, and you learn all of the language features very quickly without having to learn the GUI tools first. These early apps should be simple enough that you won’t need to use any real debugging tools to make them work.

If nothing else things like FizzBuzz are good projects. Your first few apps should not have to deal with DBs, file system, configuration, ect. These are concepts which just confuse most people, and when you’re just learning the syntax and basic framework features you really don’t need more complexity.

Some projects:

  • Hello World!
  • Take the year of my birth, and calculate my age (just (now – then) no month corrections). (simple math, input, output)
  • Ask for a direction(Up, down, left, right), then tell the user their fate (fall in a hole, find a cake, ect). (Boolean logic)
  • FizzBuzz, but count once every second. (Loops, timers, and more logic)
  • Depending on their age some really like an app which calls the users a random insult at some interval. (Loops, arrays, timers, and random if you make the interval random)

2) Simple Project Once they have a good grasp of language features, you can start a project(simple, fun games work good.). You should try to have the first project be able to be completed within 6-12 hours. Don’t spend time to architect it early. Let them design it even if it sucks. If it falls apart, talk about what happened and why it failed, then pick another topic and start again.

This is where you start introducing the debugging capabilities of your tools. Even if you can see the problem by reading the code you should teach them how to use the tools, and then show them how you could see it. That serves the dual purpose of teaching the debugging tools and teaching how to ID errors without tools.

Once, or if, the project gets functional you can use it to introduce refactoring tools. Its good if you can then expand the project with some simple features which you never planned for. This usually means refactoring and significant debugging, since very few people write even half decent code their first time.

Some projects:

  • Hangman game
  • Experimenting with robotics(Vex and Mindstorms are options)

3) Real Project Start a real project which may take some time. Use proper source control, and make a point to have a schedule. Run this project like a real project, if nothing else its good experience having to deal with the tools.

Obviously you need to adjust this for each person. The most important thing I’ve found is to make even the first simple apps apply to what the person is interested in.

Some projects:

  • Tetris
  • Text file based blog engine
  • More advanced robotics work

回答 1

您可以尝试使用Alice。这是一个3D程序,专门用于入门编程课。

新程序员的两个最大障碍通常是:

  • 语法错误
  • 动力(写一些有意义而有趣的东西,而不是做作)

爱丽丝使用拖放界面来构建程序,从而避免了语法错误的可能性。通过Alice,您可以构建3D世界,并具有代码控制(简单)的3D字符和动画,通常比实现链表更有趣。

经验丰富的程序员可能会视爱丽丝为玩具,嘲笑拖放代码行,但研究表明这种方法行之有效。

免责声明:我在Alice上工作。

You could try using Alice. It’s a 3D program designed for use in introductory programming classes.

The two biggest obstacles for new programmers are often:

  • syntax errors
  • motivation (writing something meaningful and fun rather than contrived)

Alice uses a drag and drop interface for constructing programs, avoiding the possibility of syntax errors. Alice lets you construct 3D worlds and have your code control (simple) 3D characters and animation, which is usually a lot more interesting than implementing linked lists.

Experienced programmers may look down at Alice as a toy and scoff at dragging and dropping lines of code, but research shows that this approach works.

Disclaimer: I worked on Alice.


回答 2

我推荐徽标(又名乌龟)来介绍基本概念。它提供了具有即时图形反馈的良好沙箱,并且您可以演示循环,变量,函数,条件等。此页面提供了出色的教程。

徽标后,移至Python或Ruby。我推荐Python,因为它基于ABC,它是为教学编程而发明的。

在教授编程时,我必须赞同EHaskins关于简单项目然后是复杂项目的建议。最好的学习方法是从确定的结果和可衡量的里程碑开始。它使类保持重点,允许学生建立技能,然后再利用这些技能,并给学生一些向朋友炫耀的东西。不要低估了为自己的工作展示某些东西的力量。

从理论上讲,您可以坚持使用Python,因为Python几乎可以完成任何事情。这是教授面向对象的程序设计和(大多数)算法的好工具。您可以像命令行一样在交互式模式下运行Python,以了解其工作方式,或一次运行整个脚本。您可以动态运行解释的脚本,也可以将它们编译为二进制文件。有成千上万的模块可以扩展功能。您可以制作与Windows捆绑在一起的图形计算器一样的图形计算器,也可以制作IRC客户端或其他任何东西。

XKCD更好地描述了Python的功能: “你在飞!怎么样?”  “Python!”

之后,您可以迁移到C#或Java,尽管它们没有提供Python所没有的很多功能。这些方法的好处是它们使用C语言风格的语法,许多(我敢说最多吗?)语言都使用C语言风格的语法。您无需担心内存管理,但是您可以习惯使用语言解释器的更多自由和更少的处理。Python强制使用空格和缩进,这在大多数情况下是很好的,但并非总是如此。使用C#和Java,您可以在保持强类型的同时管理自己的空格。

从那里开始,标准就是C或C ++。这些语言的自由几乎是存在的。现在,您将负责自己的内存管理。没有垃圾收集可以帮助您。在这里,您可以教授真正的高级算法(例如mergesort和quicksort)。在这里,您可以了解为什么“细分错误”是一个诅咒词。在这里,您可以下载Linux内核的源代码并凝视Abyss。首先编写循环缓冲区和用于字符串操作的堆栈。然后继续前进。

I recommend Logo (aka the turtle) to get the basic concepts down. It provides a good sandbox with immediate graphical feedback, and you can demostrate loops, variables, functions, conditionals, etc. This page provides an excellent tutorial.

After Logo, move to Python or Ruby. I recommend Python, as it’s based on ABC, which was invented for the purpose of teaching programming.

When teaching programming, I must second EHaskins’s suggestion of simple projects and then complex projects. The best way to learn is to start with a definite outcome and a measurable milestone. It keeps the lessons focused, allows the student to build skills and then build on those skills, and gives the student something to show off to friends. Don’t underestimate the power of having something to show for one’s work.

Theoretically, you can stick with Python, as Python can do almost anything. It’s a good vehicle to teach object-oriented programming and (most) algorithms. You can run Python in interactive mode like a command line to get a feel for how it works, or run whole scripts at once. You can run your scripts interpreted on the fly, or compile them into binaries. There are thousands of modules to extend the functionality. You can make a graphical calculator like the one bundled with Windows, or you can make an IRC client, or anything else.

XKCD describes Python’s power a little better: "You're flying! How?" "Python!"

You can move to C# or Java after that, though they don’t offer much that Python doesn’t already have. The benefit of these is that they use C-style syntax, which many (dare I say most?) languages use. You don’t need to worry about memory management yet, but you can get used to having a bit more freedom and less handholding from the language interpreter. Python enforces whitespace and indenting, which is nice most of the time but not always. C# and Java let you manage your own whitespace while remaining strongly-typed.

From there, the standard is C or C++. The freedom in these languages is almost existential. You are now in charge of your own memory management. There is no garbage collection to help you. This is where you teach the really advanced algorithms (like mergesort and quicksort). This is where you learn why “segmentation fault” is a curse word. This is where you download the source code of the Linux kernel and gaze into the Abyss. Start by writing a circular buffer and a stack for string manipulation. Then work your way up.


回答 3

麻省理工学院的《使用Python编程的温和介绍》是一门很好的python类。它全部在线免费提供,您不必一定要成为MIT超级学生才能了解它。

编辑[ 贾斯汀标准版 ]

本类使用这本免费的在线书籍:如何像计算机科学家一样思考
我绝对会发现它非常有用。

A good python course is MIT’s A Gentle Introduction to Programming Using Python. It’s all free online, and you don’t have to be an MIT uberstudent to understand it.

Edit [Justin Standard]

This course uses this free online book: How To Think Like a Computer Scientist
I’m definitely finding it quite useful.


回答 4

Python软件包VPython-普通凡人的3D编程(视频教程)。

代码示例:

from visual import *

floor = box (pos=(0,0,0), length=4, height=0.5, width=4, color=color.blue)
ball = sphere (pos=(0,4,0), radius=1, color=color.red)
ball.velocity = vector(0,-1,0)
dt = 0.01

while 1:
    rate (100)
    ball.pos = ball.pos + ball.velocity*dt
    if ball.y < ball.radius:
        ball.velocity.y = -ball.velocity.y
    else:
        ball.velocity.y = ball.velocity.y - 9.8*dt

VPython弹跳球http://vpython.org/bounce.gif

Python package VPython — 3D Programming for Ordinary Mortal (video tutorial).

Code example:

from visual import *

floor = box (pos=(0,0,0), length=4, height=0.5, width=4, color=color.blue)
ball = sphere (pos=(0,4,0), radius=1, color=color.red)
ball.velocity = vector(0,-1,0)
dt = 0.01

while 1:
    rate (100)
    ball.pos = ball.pos + ball.velocity*dt
    if ball.y < ball.radius:
        ball.velocity.y = -ball.velocity.y
    else:
        ball.velocity.y = ball.velocity.y - 9.8*dt

VPython bouncing ball http://vpython.org/bounce.gif


回答 5

从Python中的Turtle图形开始。

我将使用Python随附的乌龟图形。它是直观,简单的,您可以在不深入语法的情况下使用此环境引入许多编程概念,例如迭代和过程调用。考虑以下python中的交互式会话:

>>> from turtle import *
>>> setup()
>>> title("turtle test")
>>> clear()
>>>
>>> #DRAW A SQUARE
>>> down()        #pen down
>>> forward(50)   #move forward 50 units
>>> right(90)     #turn right 90 degrees
>>> forward(50)
>>> right(90)
>>> forward(50)
>>> right(90)
>>> forward(50)
>>>
>>> #INTRODUCE ITERATION TO SIMPLIFY SQUARE CODE
>>> clear()
>>> for i in range(4):
        forward(50)
        right(90)
>>>
>>> #INTRODUCE PROCEDURES   
>>> def square(length):
        down()
        for i in range(4):
            forward(length)
            right(90)
>>>
>>> #HAVE STUDENTS PREDICT WHAT THIS WILL DRAW
>>> for i in range(50):
        up()
        left(90)
        forward(25)
        square(i)
>>>
>>> #NOW HAVE THE STUDENTS WRITE CODE TO DRAW
>>> #A SQUARE 'TUNNEL' (I.E. CONCENTRIC SQUARES
>>> #GETTING SMALLER AND SMALLER).
>>>
>>> #AFTER THAT, MAKE THE TUNNEL ROTATE BY HAVING
>>> #EACH SUCCESSIVE SQUARE TILTED

在尝试完成最后两个任务时,他们将进行很多失败的尝试,但是这些失败在视觉上将是有趣的,并且他们将很快学会,因为他们试图弄清为什么它没有达到他们的期望。

Begin with Turtle graphics in Python.

I would use the turtle graphics which comes standard with Python. It is visual, simple and you could use this environment to introduce many programming concepts like iteration and procedure calls before getting too far into syntax. Consider the following interactive session in python:

>>> from turtle import *
>>> setup()
>>> title("turtle test")
>>> clear()
>>>
>>> #DRAW A SQUARE
>>> down()        #pen down
>>> forward(50)   #move forward 50 units
>>> right(90)     #turn right 90 degrees
>>> forward(50)
>>> right(90)
>>> forward(50)
>>> right(90)
>>> forward(50)
>>>
>>> #INTRODUCE ITERATION TO SIMPLIFY SQUARE CODE
>>> clear()
>>> for i in range(4):
        forward(50)
        right(90)
>>>
>>> #INTRODUCE PROCEDURES   
>>> def square(length):
        down()
        for i in range(4):
            forward(length)
            right(90)
>>>
>>> #HAVE STUDENTS PREDICT WHAT THIS WILL DRAW
>>> for i in range(50):
        up()
        left(90)
        forward(25)
        square(i)
>>>
>>> #NOW HAVE THE STUDENTS WRITE CODE TO DRAW
>>> #A SQUARE 'TUNNEL' (I.E. CONCENTRIC SQUARES
>>> #GETTING SMALLER AND SMALLER).
>>>
>>> #AFTER THAT, MAKE THE TUNNEL ROTATE BY HAVING
>>> #EACH SUCCESSIVE SQUARE TILTED

In trying to accomplish the last two assignments, they will have many failed attempts, but the failures will be visually interesting and they’ll learn quickly as they try to figure out why it didn’t draw what they expected.


回答 6

关键是有问题的人需要解决一些问题。如果您没有要编写的程序(以及一些明智且定义明确的程序,而不是“我要编写下一本Quake!”),则您将无法学习编程,因为您没有动力去激励自己。 。我的意思是,您可以读一本书,并对语言的语法和语义有一个大概的了解,但是除非您拥有要编写的程序,否则您将永远无法理解。

如果存在这种推动力,那么其他所有内容都只是次要的细节。

The key thing is that the person in question needs to have some problem that they want solving. If you don’t have a program that you want to write (and something sensible and well-defined, not “I want to write the next Quake!”) then you can’t learn to program, because you have nothing to motivate you. I mean, you could read a book and have a rough understanding of a language’s syntax and semantics, but until you have a program that you want written you’ll never grasp the nettle.

If that impetus exists then everything else is just minor details.


回答 7

我不知道这里是否有人提到过,但是您可能想看看Zed Shaw的学习Python的艰难方法》

希望这可以帮助

I don’t know if anyone has mentioned this here, yet, but You might want to check out Zed Shaw‘s Learn Python the Hard Way

Hope this Helps


回答 8

http://tryruby.hobix.com/“>尝试使用Ruby(在您的浏览器中)

http://tryruby.hobix.com/”>Try Ruby (In Your Browser)


回答 9


回答 10

这是一本很棒的书,我的小兄弟曾经学习过:

http://pine.fm/LearnToProgram/

当然,最重要的是在读完本书后立即开始一个真正有用的某种程序。

This is a fantastic book which my little brothers used to learn:

http://pine.fm/LearnToProgram/

Of course, the most important thing is to start on a real, useful program of some kind IMMEDIATELY after finishing the book.


回答 11

如果他有兴趣,次要细节不是很好的部分吗?使用python,您已经将它的GUI切断了,这样混乱就消失了。为什么不选择一个项目,一个游戏之类的东西并实现它。经典的hi-lo数字猜谜游戏可以在命令行中以20-30行代码(具体取决于语言)简单地实现,并为您提供变量,条件,循环和用户输入。

If he’s interested, aren’t the minor details the good parts? Using python, you’ve already cut the GUI off of it so that confusion is gone. Why not pick a project, a game or something, and implement it. The classic hi-lo number guessing game can be simply implemented from the command line in 20-30 lines of code (depending on language of course) and gives you variables, conditions, loops, and user input.


回答 12

我只是让他写大量的代码。让他开车去做你们所做的一切,并且随时可以回答问题。

信不信由你,经过几个月的编写大量笨拙的代码之后,他将开始明白这个想法,并开始编写更好的程序。到那时,您可以陷入细节(内存等)的泥潭,还可以讨论一般的设计原则。

我听说,伟大的艺术家与平庸的艺术家之间的区别是,每一次练习,无论大小,他们都会有所进步。让您的兄弟练习一下,他每次坐在键盘上都会使他进步。

编辑:[贾斯汀标准]

埃斯特万,这让我想起最近的编码恐怖后,我认为你是对的。但是我认为仍然值得寻找方法来指导他的实践。没问题,我希望他编写尽可能多的代码。这就是我要样例项目的原因之一。

I’d just let him write tons of code. Let him drive in everything you guys do, and just be available to answer questions.

Believe it or not, after a few months of writings tons of crappy code, he’ll start to get the idea and start writing better programs. At that point, you can get bogged down in details (memory, etc), and also talk about general design principles.

I’ve heard that what separates the great artists from the mediocre ones, is that every time they practice, they improve on something, no matter how small. Let your brother practice, and he’ll improve every time he sits down at the keyboard.

Edit: [Justin Standard]

Esteban, this reminds me of a recent coding horror post, and I do think you are right. But I think its still worthwhile to find methods to guide his practice. No question, I want him writing as much code as he knows how to do. Thats one reason I’m asking for sample projects.


回答 13

首先,像其他所有人一样开始工作:使用Hello World程序。这很简单,并且给了他们基本的程序布局感觉。尝试回想起您第一次编程的时间以及其中一些概念的难易程度-从简单开始。

在Hello World之后,继续创建一些基本变量,算术,然后创建布尔逻辑和if / else语句。如果您有一本旧的编程教科书,请查看一些早期示例,并让他复习这些示例。只是不要尝试一次过多地介绍所有内容,否则将会使您感到困惑和困惑。

First of all, start out like everyone else does: with a Hello World program. It’s simple, and it gives them a basic feel for the layout of a program. Try and remember back to when you were first programming, and how difficult some of the concepts were – start simple.

After Hello World, move on to creating some basic variables, arithmetic, then onto boolean logic and if/else statements. If you’ve got one of your old programming textbooks, check out some of the early examples and have him run through those. Just don’t try to introduce too much all at once, or it will be overwhelming and confusing.


回答 14

在教您的兄弟编程时,您应该谨记的一点是,不要太依赖您。通常,当我发现自己在帮助他人时,他们会开始将我视为所有问题的答案书,而不是尝试寻找答案,他们只是问我。通常最好的老师是实验,每当您的兄弟有一个问题,例如“如果我在字符串中加2,会发生什么?”。您应该告诉他尝试一下,亲自看看。我还注意到,当我无法将概念传达给某人时,这有助于查看一些示例代码,在这里我们可以分别查看每个段并逐个进行解释。附带说明一下,刚接触编程的人经常会遇到面向对象编程的想法,

Something you should be very mindful of while teaching your brother to program is for him not to rely too heavily on you. Often when I find myself helping others they will begin to think of me as answer book to all of their questions and instead of experimenting to find an answer they simply ask me. Often the best teacher is experimentation and every time your brother has a question like “What will happen if I add 2 to a string?” you should tell him to try it out and see for himself. Also I have noticed that when I cannot get a concept through to someone, it helps to see some sample code where we can look at each segment individually and explain it piece by piece. As a side note people new to programming often have trouble with the idea of object oriented programming, they will say they understand it when you teach it to them but will not get a clear concept of it until actually implementing it.


回答 15

我曾经教编程,与您想学习的大多数学生相比,您的兄弟有一个主要优势:)

如果您决定和C一起去,那么一个朋友的站点会提供一些程序,这些程序可以使用较早的一代记住的基本键入程序。他们中较复杂的人使用ncurses,这在某种程度上抵消了它们作为教学辅助工具的使用,但是其中一些是很小的小东西,您无需学习即可学习负载。

我个人认为Python和Ruby将成为出色的第一语言。

编辑: 一夜之间出现的初学者编程作业列表可能正是您想要的。

I used to teach programming and your brother has one main advantage over most of my students he wants to learn :)

If you decide to go with C a friend has a site that has the sort of programs those of use from older generations remember as basic type-ins. The more complex of them use ncurses which sort of negates their use as a teaching aid somewhat but some of them are tiny little things and you can learn loads without being taught to.

Personally I think Python and Ruby would make great first languages.

EDIT: list of beginner programming assignments appeared overnight might be just what you are looking for.


回答 16

这确实取决于您兄弟的学习风格。许多人会变得肮脏,只有动手才能学得更快,随着他们的进步和积累知识,使概念和全局变得清晰。

我,我更喜欢从大局开始,深入研究细节。我想知道的第一件事是它们如何融合在一起,然后是所有面向对象的蠢事,然后是类和实例等等。在学习语法之前,我喜欢了解基本概念和一些理论。我有一个优势,因为20年前我用BASIC编写了一些游戏,但此后没什么。

在实际编写代码之前,通过总体任务说明,计划和/或流程图,然后详细说明一些伪代码(倾向于最终使用的语法)来掩盖生产过程,这可能是有用的。

这里的黄金法则是保持学生的学习风格。

It really depends on your brother’s learning style. Many people learn faster by getting their hands dirty & just getting into it, crystallising the concepts and the big picture as they progress and build their knowledge.

Me, I prefer to start with the big picture and drill down into the nitty-gritty. The first thing I wanted to know was how it all fits together then all that Object-oriented gobbledygook, then about classes & instances and so-on. I like to know the underlying concepts and a bit of theory before I learn the syntax. I had a bit of an advantage because I wrote some games in BASIC 20 years ago but nothing much since.

Perhaps it is useful to shadow a production process by starting with an overall mission statement, then a plan and/or flowchart, then elaborate into some pseudo code (leaning towards the syntax you will ultimately use) before actually writing the code.

The golden rule here is to suss out your student’s leaning style.


回答 17

如果您的兄弟可以使用iTunes,则可以下载新南威尔士大学的Richard Buckland开设的计算机科学入门类的视频讲座。他是一位引人入胜的讲师,涵盖计算和C语言的基础知识。如果没有其他要求,请告诉您的兄弟在后台播放视频,某些概念可能会因渗透而陷入。:)

COMP1917高等计算-2008会话1 http://deimos3.apple.com/WebObjects/Core.woa/Browse/unsw.edu.au.1504975442.01504975444

如果链接不起作用,请使用以下路径:

主页-> iTunes U->工程-> COMP1917高等计算-2008第1节

If your brother has access to iTunes, he can download video lectures of an introductory computer science course given by Richard Buckland at the University of New South Wales. He’s an engaging instructor and covers fundamentals of computing and the C language. If nothing else, tell your brother to play the vids in the background and some concepts might sink in through osmosis. :)

COMP1917 Higher Computing – 2008 Session 1 http://deimos3.apple.com/WebObjects/Core.woa/Browse/unsw.edu.au.1504975442.01504975444

If the link doesn’t work, here’s a path:

Home -> iTunes U –> Engineering –> COMP1917 Higher Computing – 2008 Session 1


回答 18

有一本非常适合学习python的Wikibook

我不知道其他语言的Wikibook怎么样,但是我个人从Wikibook中学习了python,就像2007年2月一样

ps-如果您不熟悉Wikibook,则基本上是书籍创作的Wikipedia版本。这很难描述,但是如果您查看那里的几本书,就会知道它是如何工作的

there’s a wikibook that is pretty good for learning python.

I don’t know how the wikibooks are for other languages, but I personally learned python from the wikibook as it was in Feb 2007

ps – if you’re unfamiliar with wikibooks, it’s basically the wikipedia version of book authoring. it’s sort of hard to describe, but if you check out a few of the books on there you’ll see how it works


回答 19


回答 20

我认为Python是个好主意。我会给他一些基本任务,让他自己做,并告诉他,他遇到的任何死胡同都可以通过去Google来解决。至少对我来说,独自解决一个问题总是比别人告诉我解决方案更好。

一些可能的项目(无特定顺序):

  • 硬币翻转模拟器。让用户输入所需的硬币投掷次数。执行它并显示结果以及正面或反面的百分比。

  • 使用带有菜单的温度转换器,该菜单需要用户输入以选择用户想要执行的转换类型。选择转换并完成转换后,应返回主菜单。

    这是具有相同概念的扩展转换器的示例:http : //pastebin.org/6541

  • 编写一个使用数字输入并显示要转换为的字母等级的程序。最终将根据if和elif语句评估输入,以找到适合的位置。

  • 进行一次简单的测验,以进行多项选择或填写空白问题。最后,它将显示用户的操作方式。他可以选择任何想要的问题。

  • 输入一些(可能很大)的便士,并将其转换成更大的面额。例如,149便士= 1美元,1个季度,2个角钱和4个便士。

  • 创建一个简单的列表管理器。能够添加/删除列表以及在这些列表中添加/删除条目。这是圣诞节清单管理器的示例:http : //pastebin.org/6543

  • 创建一个将生成的程序,然后测试输入的数字是否形成一个魔方(带有2D数组)。这是一些示例代码,但实际上应该在每个步骤中打印出正方形,以显示用户在正方形上的位置:http : //pastebin.org/6544

我还建议使用xTurtle或其他图形模块做一些事情,以使事情变得混乱,并避免他变得无聊。当然,这是非常实际的编程,而不是很多人真正会使用python的脚本,但是我给出的示例几乎直接取自于我通过python学习时,并且对我来说非常有用。祝好运!

I think Python is a great idea. I would give him a few basic assignments to do on his own and tell him that any dead ends he hits can probably be resolved by a trip to google. For me, at least, solving a problem on my own always made it stick better than someone telling me the solution.

Some possible projects (in no particular order):

  • Coin flip simulator. Let the user input a desired number of trials for the coin flipping. Execute it and display the results along with the percentage for heads or tails.

  • Make a temperature converter with a menu that takes user input to choose which kind of conversion the user wants to do. After choosing the conversion and doing it, it should return to the main menu.

    Here’s an example of an extended converter with the same idea: http://pastebin.org/6541

  • Make a program that takes a numeric input and displays the letter grade it would translate to. It’ll end up evaluating the input against if and elif statements to find where it fits.

  • Make a simple quiz that goes through several multiple choice or fill in the blank questions. At the end it will display how the user did. He can pick any questions he wants.

  • Take an input of some (presumably large) number of pennies and convert it into bigger denominations. For example, 149 pennies = 1 dollar, 1 quarter, 2 dimes, and 4 pennies.

  • Create a simple list manager. Be able to add/delete lists and add/delete entries in those lists. Here’s an example of a christmas list manager: http://pastebin.org/6543

  • Create a program that will build and then test whether entered numbers form a magic square (with a 2D array). Here’s some sample code, but it should really print out the square at each step in order to show where the user is in terms of buliding the square: http://pastebin.org/6544

I would also suggest doing some stuff with xTurtle or another graphics module to mix things up and keep him from getting boring. Of course, this is very much practice programming and not the scripting that a lot of people would really be using python for, but the examples I gave are pretty much directly taken from when I was learning via python and it worked out great for me. Good luck!


回答 21

只是取笑!

令人惊讶的是,如果您尝试Kojo, Scala可能是最简单的

Just make it fun !

Amazingly Scala might be the easiest if you try Kojo


回答 22

如果您的兄弟喜欢拼图,我建议您使用Python Challenge。在一对一的教程中,我不会将其用作正式的教学工具,但是当您不在一起挑战自己并享受一些乐趣时,他可以做这件事。

If your brother likes puzzles, I would recommend Python Challenge. I wouldn’t use it as a formal teaching tool in a 1 on 1 tutorial, but it’s something he can do when you’re not together to challenge himself and have some fun.


回答 23


回答 24

在浏览了几本免费的电子书之后,我发现最适合学习编程的书是O’Reily Press出版的Head First Programming。它使用Python作为语言,并从一开始就为您提供要处理的程序。他们比“ Hello World”更有趣。我花在上面的钱很值得,而且由于花了一点时间,您也许可以在Ebay或Amazon上找到更便宜的二手书。

After going through a few free e-books, I found the best book for learning to program was Head First Programming published by O’Reily Press. It uses Python as the language and gives you programs to work on from the very start. They are all more interesting that ‘Hello World’. It’s well worth the money I spent on it, and since it’s been out for a bit you may be able to find a cheaper used copy on Ebay or Amazon.


回答 25

如果您想教编程的基础知识,而又不特定于语言,则有一个名为 在MIT中创建 Scratch。它旨在帮助人们发展编程技能。用户创建Scratch项目时,他们会学习创建条件,循环等。还有一个Scratch项目社区,可以下载项目的表单-这样,您就可以浏览其他人的程序并查看其构建方式。

If you want to teach the basics of programming, without being language specific, there is an application called Scratch that was created in MIT. It’s designed to help people develop programming skills. As users create Scratch projects, they learn to create conditions, loops, etc. There is a also a community of scratch projects, form which projects can be downloaded – that way you can explore other people’s programs and see how they were built.


回答 26

我认为,一旦他掌握了基础知识(变量,循环等),就应该尝试帮助他找到他感兴趣的特定事物,并帮助他了解实现它的必要性。我知道,如果我感兴趣的话,我会更倾向于做某事。另外,确保让他为一些棘手的问题而奋斗,没有什么比自己解决这个问题更令人满意的了。

I think that once he has the basics (variables, loops, etc) down you should try to help him find something specific that he is interested in and help him learn the necessities to make it happen. I know that I am much more inclined and motivated to do something if it’s of interest to me. Also, make sure to let him struggle though some of the tougher problems, nothing is more satisfying than the moment you figure it out on your own.


回答 27

通过学习如何使用流程图和PDL以与语言无关的方式解决问题,使我受到了教育(程序设计语言)。几周后,我学会了将编写的PDL转换为语言。我很高兴能以这种方式学习,因为我花了大部分时间来编程,解决了各种问题,而又不受语言的束缚。我使用的语言一直是实现细节,而不是设计的一部分。

必须通过将问题分解为基本步骤来解决问题是一项关键技能。我认为这是将那些可以编程的人与那些不能编程的人分开的事情之一。

就如何处理语言概念的顺序而言,我认为最简单的方法是决定要考虑一个项目并根据需要解决这些概念。这样,您就可以根据需要将它们应用到您感兴趣的事情上。学习语言时,最好记住几个简单的项目,而一些项目要具有渐进的复杂性。确定这些内容将帮助您确定所需的概念及其顺序。

I was taught by learning how to solve problems in a language agnostic way using flowcharts and PDL (Program Design Language). After a couple weeks of that, I learned to convert the PDL I had written to a language. I am glad I learned that way because I have spent the majority of my years programming, solving problems without being tied to a language. What language I use has always been an implementation detail and not part of the design.

Having to solve the problem by breaking it down into it’s basic steps is a key skill. I think it is one of the things that separates those that can program from those that can’t.

As far as how you tackle the order of concepts of a language I believe the easiest way is to decide that is to have a project in mind and tackle the concepts as they are needed. This lets you apply them as they are needed on something that you are interested in doing. When learning a language it is good to have several simple projects in mind and a few with progressive complexity. Deciding on those will help you map out the concepts that are needed and their order.


回答 28

我还建议您观看一些截屏视频-它们通常是在特定技术而非语言的背景下创建的,尽管如果显示Python代码,则可以:)。关键是-它们是由一些优秀的程序员创建的,看着优秀的程序员编程是一件好事。您和您的兄弟也可以进行一些对等编程,这可能是一个更好的主意。只是别忘了解释为什么您要以这种方式而不是那样的方式做事。我认为学习编程的最好方法是从好的例子中去,甚至不要去看坏的例子。

I would recommend also watching some screencasts – they are generally created in context of a specific technology not a language, though if there’s Python code displayed, that’ll do :). The point is – they’re created by some good programmers and watching how good programmers program is a good thing. You and your brother could do some peer programming as well, that might be an even better idea. Just don’t forget to explain WHY you do something this way and not that way. I think the best way to learn programming is from good examples and try not to even see the bad ones.


回答 29

罗伯特·雷德(Robert Read)撰写了一份有用的指南,《如何成为程序员》,其中涵盖了初学者会有所帮助的广泛编程问题。

Robert Read wrote a useful guide, How to be a Programmer, which covers a wide area of programming issues that a beginner would find helpful.


为什么“ except:pass”是不好的编程习惯?

问题:为什么“ except:pass”是不好的编程习惯?

我经常看到有关except: pass不鼓励使用的其他Stack Overflow问题的评论。为什么这样不好?有时我只是不在乎错误是什么,我只想继续编写代码。

try:
    something
except:
    pass

为什么使用except: pass积木不好?是什么让它不好?是我pass出错还是我except出错了?

I often see comments on other Stack Overflow questions about how the use of except: pass is discouraged. Why is this bad? Sometimes I just don’t care what the errors, are and I want to just continue with the code.

try:
    something
except:
    pass

Why is using an except: pass block bad? What makes it bad? Is it the fact that I pass on an error or that I except any error?


回答 0

正如您正确猜测的那样,它有两个方面:通过在之后不指定任何异常类型来捕获任何错误except,并在不采取任何操作的情况下简单地传递它。

我的解释是“更长”的时间,所以tl; dr可以细分为:

  1. 不要发现任何错误。始终指定您准备从中恢复的异常,并且仅捕获这些异常。
  2. 尽量避免传入除了blocks。除非明确要求,否则通常不是一个好兆头。

但是,让我们详细介绍一下:

不要发现任何错误

使用try块时,通常这样做是因为您知道有可能引发异常。这样,您还已经大概知道了哪些会中断,哪些异常会引发。在这种情况下,您会捕获异常,因为您可以从中积极地恢复过来。这意味着您已为exceptions做好了准备,并有一些替代计划,在发生这种exceptions时将遵循该计划。

例如,当您要求用户输入数字时,您可以使用int()可能引起的转换输入ValueError。您可以简单地要求用户再试一次,从而轻松地恢复它,因此捕获ValueError并再次提示用户将是一个适当的计划。一个不同的例子是,如果您想从文件中读取某些配置,而该文件恰好不存在。因为它是一个配置文件,所以您可能具有一些默认配置作为后备,因此该文件并非完全必要。因此,FileNotFoundError在此处捕获并简单地应用默认配置将是一个不错的计划。现在,在这两种情况下,我们都期望有一个非常具体的exceptions,并且有一个同样具体的计划可以从中恢复。因此,在每种情况下,我们只明确except 某些 exceptions。

但是,如果我们要抓住一切,那么除了准备好从那些异常中恢复过来,我们还有机会获得我们没有想到的异常,而我们确实无法从中恢复。或不应从中恢复。

让我们以上面的配置文件示例为例。如果文件丢失,我们将应用默认配置,并可能在以后决定自动保存配置(因此下次该文件存在)。现在想象我们得到一个IsADirectoryError或一个PermissionError代替。在这种情况下,我们可能不想继续。我们仍然可以应用默认配置,但是以后将无法保存文件。而且用户可能也打算具有自定义配置,因此可能不需要使用默认值。因此,我们希望立即将其告知用户,并且可能也中止程序执行。但这不是我们想要在某些小代码部分的深处做的事情。这在应用程序级别上很重要,因此应该在顶部进行处理-因此让异常冒出来。

Python 2习惯用法文档中还提到了另一个简单的示例。在这里,代码中存在一个简单的错字,导致它中断。因为我们正在捕获每个异常,所以我们也捕获了NameErrorsSyntaxErrors。两者都是编程时我们所有人都会遇到的错误。两者都是我们在交付代码时绝对不希望包含的错误。但是,因为我们也抓住了它们,所以我们甚至都不知道它们在那里发生,并且失去了正确调试它的任何帮助。

但是,还有一些危险的exceptions情况,我们不太可能为此做好准备。例如,SystemError通常很少发生,我们无法真正计划。这意味着发生了一些更复杂的事情,有可能阻止我们继续当前的任务。

无论如何,您几乎不可能为代码中的一小部分做好一切准备,因此,实际上,您应该只捕获准备好的那些异常。有人建议至少要赶上Exception它,因为它不会包含类似的内容,SystemExitKeyboardInterrupt这些内容在设计上是要终止您的应用程序的,但是我认为这仍然过于不确定。我个人只在一个地方接受捕捞活动,Exception或者在任何地方异常,并且在单个全局应用程序级异常处理程序中,该异常处理程序的唯一目的是记录我们没有准备好的任何异常。这样,我们仍然可以保留有关意外异常的尽可能多的信息,然后我们可以使用这些信息来扩展代码以显式处理这些异常(如果可以从异常中恢复),或者在发生错误的情况下创建测试用例以确保它不会再发生。但是,当然,只有当我们只捕获到我们已经期望的异常时,这才起作用,所以我们没有想到的异常自然会冒出来。

尽量避免传入除了块

当显式地捕获少量特定异常时,在许多情况下,只要不执行任何操作就可以了。在这种情况下,拥有except SomeSpecificException: pass就好。不过,在大多数情况下,情况并非如此,因为我们可能需要一些与恢复过程相关的代码(如上所述)。例如,这可以是重试该操作的内容,也可以是设置默认值的内容。

但是,如果不是这种情况,例如因为我们的代码已经被构造为可以重复执行直到成功,那么传递就足够了。从上面的例子中,我们可能想要求用户输入一个数字。因为我们知道用户不想按照我们的要求去做,所以我们可能首先将其放入循环中,因此看起来可能像这样:

def askForNumber ():
    while True:
        try:
            return int(input('Please enter a number: '))
        except ValueError:
            pass

因为我们一直努力直到没有异常抛出,所以我们不需要在except块中做任何特殊的事情,所以这很好。但是,当然,有人可能会认为我们至少要向用户显示一些错误消息,以告诉他为什么他必须重复输入。

但是,在许多其他情况下,仅传递except一个信号就表明我们并未真正为所捕获的异常做好准备。除非这些异常很简单(如ValueErrorTypeError),并且我们可以通过的原因很明显,否则请尝试避免仅通过。如果真的无事可做(您对此绝对有把握),则考虑添加评论,为什么会这样;否则,展开except块以实际包括一些恢复代码。

except: pass

不过,最严重的罪犯是两者的结合。这意味着我们乐于捕捉任何错误,尽管我们绝对没有为此做好准备,并且我们也不对此做任何事情。您至少要记录该错误,还可能重新引发该错误以仍然终止应用程序(在出现MemoryError后,您不太可能像往常一样继续操作)。只是传递信息不仅可以使应用程序保持一定的生命力(当然,还取决于您捕获的位置),而且还会丢弃所有信息,从而无法发现错误-如果您不是发现错误的人,则尤其如此。


因此,底线是:仅捕获您真正期望并准备从中恢复的异常;其他所有问题都可能是您应纠正的错误,或者您没有准备好应对。如果您真的不需要对异常进行处理,则传递特定的异常很好。在其他所有情况下,这只是推定和懒惰的标志。您肯定想解决该问题。

As you correctly guessed, there are two sides to it: Catching any error by specifying no exception type after except, and simply passing it without taking any action.

My explanation is “a bit” longer—so tl;dr it breaks down to this:

  1. Don’t catch any error. Always specify which exceptions you are prepared to recover from and only catch those.
  2. Try to avoid passing in except blocks. Unless explicitly desired, this is usually not a good sign.

But let’s go into detail:

Don’t catch any error

When using a try block, you usually do this because you know that there is a chance of an exception being thrown. As such, you also already have an approximate idea of what can break and what exception can be thrown. In such cases, you catch an exception because you can positively recover from it. That means that you are prepared for the exception and have some alternative plan which you will follow in case of that exception.

For example, when you ask for the user to input a number, you can convert the input using int() which might raise a ValueError. You can easily recover that by simply asking the user to try it again, so catching the ValueError and prompting the user again would be an appropriate plan. A different example would be if you want to read some configuration from a file, and that file happens to not exist. Because it is a configuration file, you might have some default configuration as a fallback, so the file is not exactly necessary. So catching a FileNotFoundError and simply applying the default configuration would be a good plan here. Now in both these cases, we have a very specific exception we expect and have an equally specific plan to recover from it. As such, in each case, we explicitly only except that certain exception.

However, if we were to catch everything, then—in addition to those exceptions we are prepared to recover from—there is also a chance that we get exceptions that we didn’t expect, and which we indeed cannot recover from; or shouldn’t recover from.

Let’s take the configuration file example from above. In case of a missing file, we just applied our default configuration, and might decided at a later point to automatically save the configuration (so next time, the file exists). Now imagine we get a IsADirectoryError, or a PermissionError instead. In such cases, we probably do not want to continue; we could still apply our default configuration, but we later won’t be able to save the file. And it’s likely that the user meant to have a custom configuration too, so using the default values is likely not desired. So we would want to tell the user about it immediately, and probably abort the program execution too. But that’s not something we want to do somewhere deep within some small code part; this is something of application-level importance, so it should be handled at the top—so let the exception bubble up.

Another simple example is also mentioned in the Python 2 idioms document. Here, a simple typo exists in the code which causes it to break. Because we are catching every exception, we also catch NameErrors and SyntaxErrors. Both are mistakes that happen to us all while programming; and both are mistakes we absolutely don’t want to include when shipping the code. But because we also caught those, we won’t even know that they occurred there and lose any help to debug it correctly.

But there are also more dangerous exceptions which we are unlikely prepared for. For example SystemError is usually something that happens rarely and which we cannot really plan for; it means there is something more complicated going on, something that likely prevents us from continuing the current task.

In any case, it’s very unlikely that you are prepared for everything in a small scale part of the code, so that’s really where you should only catch those exceptions you are prepared for. Some people suggest to at least catch Exception as it won’t include things like SystemExit and KeyboardInterrupt which by design are to terminate your application, but I would argue that this is still far too unspecific. There is only one place where I personally accept catching Exception or just any exception, and that is in a single global application-level exception handler which has the single purpose to log any exception we were not prepared for. That way, we can still retain as much information about unexpected exceptions, which we then can use to extend our code to handle those explicitly (if we can recover from them) or—in case of a bug—to create test cases to make sure it won’t happen again. But of course, that only works if we only ever caught those exceptions we were already expecting, so the ones we didn’t expect will naturally bubble up.

Try to avoid passing in except blocks

When explicitly catching a small selection of specific exceptions, there are many situations in which we will be fine by simply doing nothing. In such cases, just having except SomeSpecificException: pass is just fine. Most of the time though, this is not the case as we likely need some code related to the recovery process (as mentioned above). This can be for example something that retries the action again, or to set up a default value instead.

If that’s not the case though, for example because our code is already structured to repeat until it succeeds, then just passing is good enough. Taking our example from above, we might want to ask the user to enter a number. Because we know that users like to not do what we ask them for, we might just put it into a loop in the first place, so it could look like this:

def askForNumber ():
    while True:
        try:
            return int(input('Please enter a number: '))
        except ValueError:
            pass

Because we keep trying until no exception is thrown, we don’t need to do anything special in the except block, so this is fine. But of course, one might argue that we at least want to show the user some error message to tell him why he has to repeat the input.

In many other cases though, just passing in an except is a sign that we weren’t really prepared for the exception we are catching. Unless those exceptions are simple (like ValueError or TypeError), and the reason why we can pass is obvious, try to avoid just passing. If there’s really nothing to do (and you are absolutely sure about it), then consider adding a comment why that’s the case; otherwise, expand the except block to actually include some recovery code.

except: pass

The worst offender though is the combination of both. This means that we are willingly catching any error although we are absolutely not prepared for it and we also don’t do anything about it. You at least want to log the error and also likely reraise it to still terminate the application (it’s unlikely you can continue like normal after a MemoryError). Just passing though will not only keep the application somewhat alive (depending where you catch of course), but also throw away all the information, making it impossible to discover the error—which is especially true if you are not the one discovering it.


So the bottom line is: Catch only exceptions you really expect and are prepared to recover from; all others are likely either mistakes you should fix, or something you are not prepared for anyway. Passing specific exceptions is fine if you really don’t need to do something about them. In all other cases, it’s just a sign of presumption and being lazy. And you definitely want to fix that.


回答 1

这里的主要问题是它会忽略所有错误:内存不足,CPU正在燃烧,用户想要停止,程序想要退出,Jabberwocky正在杀死用户。

这太多了。在您的脑海中,您正在思考“我想忽略此网络错误”。如果出乎意料的地方出了问题,那么您的代码将以无人能及的方式以无法预测的方式静默继续并中断。

这就是为什么您应该将自己限制为仅忽略某些错误,而让其余错误通过。

The main problem here is that it ignores all and any error: Out of memory, CPU is burning, user wants to stop, program wants to exit, Jabberwocky is killing users.

This is way too much. In your head, you’re thinking “I want to ignore this network error”. If something unexpected goes wrong, then your code silently continues and breaks in completely unpredictable ways that no one can debug.

That’s why you should limit yourself to ignoring specifically only some errors and let the rest pass.


回答 2

从字面上执行伪代码甚至不会给出任何错误:

try:
    something
except:
    pass

就像是一段完全有效的代码,而不是抛出NameError。我希望这不是您想要的。

Executing your pseudo code literally does not even give any error:

try:
    something
except:
    pass

as if it is a perfectly valid piece of code, instead of throwing a NameError. I hope this is not what you want.


回答 3

为什么“ except:pass”是不好的编程习惯?

为什么这样不好?

try:
    something
except:
    pass

这会捕获所有可能的异常,包括GeneratorExitKeyboardInterruptSystemExit-这是您可能不打算捕获的异常。和赶上一样BaseException

try:
    something
except BaseException:
    pass

版本的文档说

由于Python中的每个错误都会引发一个异常,因此使用except:可能会使许多编程错误看起来像运行时问题,从而阻碍了调试过程。

Python异常层次结构

如果捕获父异常类,那么还将捕获其所有子类。仅捕获您准备处理的异常要优雅得多。

这是Python 3 异常层次结构 -您是否真的想抓住一切?:

BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception
      +-- StopIteration
      +-- StopAsyncIteration
      +-- ArithmeticError
      |    +-- FloatingPointError
      |    +-- OverflowError
      |    +-- ZeroDivisionError
      +-- AssertionError
      +-- AttributeError
      +-- BufferError
      +-- EOFError
      +-- ImportError
           +-- ModuleNotFoundError
      +-- LookupError
      |    +-- IndexError
      |    +-- KeyError
      +-- MemoryError
      +-- NameError
      |    +-- UnboundLocalError
      +-- OSError
      |    +-- BlockingIOError
      |    +-- ChildProcessError
      |    +-- ConnectionError
      |    |    +-- BrokenPipeError
      |    |    +-- ConnectionAbortedError
      |    |    +-- ConnectionRefusedError
      |    |    +-- ConnectionResetError
      |    +-- FileExistsError
      |    +-- FileNotFoundError
      |    +-- InterruptedError
      |    +-- IsADirectoryError
      |    +-- NotADirectoryError
      |    +-- PermissionError
      |    +-- ProcessLookupError
      |    +-- TimeoutError
      +-- ReferenceError
      +-- RuntimeError
      |    +-- NotImplementedError
      |    +-- RecursionError
      +-- SyntaxError
      |    +-- IndentationError
      |         +-- TabError
      +-- SystemError
      +-- TypeError
      +-- ValueError
      |    +-- UnicodeError
      |         +-- UnicodeDecodeError
      |         +-- UnicodeEncodeError
      |         +-- UnicodeTranslateError
      +-- Warning
           +-- DeprecationWarning
           +-- PendingDeprecationWarning
           +-- RuntimeWarning
           +-- SyntaxWarning
           +-- UserWarning
           +-- FutureWarning
           +-- ImportWarning
           +-- UnicodeWarning
           +-- BytesWarning
           +-- ResourceWarning

不要这样

如果您使用这种形式的异常处理:

try:
    something
except: # don't just do a bare except!
    pass

这样,您将无法something使用Ctrl-C 中断您的代码块。您的程序将忽略try代码块内的所有可能的Exception 。

这是另一个具有相同不良行为的示例:

except BaseException as e: # don't do this either - same as bare!
    logging.info(e)

相反,请尝试仅捕获您要查找的特定异常。例如,如果您知道转换可能会产生价值错误:

try:
    foo = operation_that_includes_int(foo)
except ValueError as e:
    if fatal_condition(): # You can raise the exception if it's bad,
        logging.info(e)   # but if it's fatal every time,
        raise             # you probably should just not catch it.
    else:                 # Only catch exceptions you are prepared to handle.
        foo = 0           # Here we simply assign foo to 0 and continue. 

另一个示例的进一步说明

您之所以这样做,是因为您一直在爬网并说a UnicodeError,但是由于使用了最广泛的Exception catch,您的代码(可能有其他基本缺陷)将尝试运行至完成,浪费带宽,处理时间,设备的磨损,内存不足,收集垃圾数据等。

如果其他人要求您完成操作,以便他们可以依靠您的代码,那么我理解被迫仅处理所有事情。但是,如果您愿意在开发过程中大声失败,那么您将有机会纠正可能会间歇性出现的问题,但这将是长期的代价高昂的错误。

通过更精确的错误处理,您的代码可以更强大。

Why is “except: pass” a bad programming practice?

Why is this bad?

try:
    something
except:
    pass

This catches every possible exception, including GeneratorExit, KeyboardInterrupt, and SystemExit – which are exceptions you probably don’t intend to catch. It’s the same as catching BaseException.

try:
    something
except BaseException:
    pass

Older versions of the documentation say:

Since every error in Python raises an exception, using except: can make many programming errors look like runtime problems, which hinders the debugging process.

Python Exception Hierarchy

If you catch a parent exception class, you also catch all of their child classes. It is much more elegant to only catch the exceptions you are prepared to handle.

Here’s the Python 3 exception hierarchy – do you really want to catch ’em all?:

BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception
      +-- StopIteration
      +-- StopAsyncIteration
      +-- ArithmeticError
      |    +-- FloatingPointError
      |    +-- OverflowError
      |    +-- ZeroDivisionError
      +-- AssertionError
      +-- AttributeError
      +-- BufferError
      +-- EOFError
      +-- ImportError
           +-- ModuleNotFoundError
      +-- LookupError
      |    +-- IndexError
      |    +-- KeyError
      +-- MemoryError
      +-- NameError
      |    +-- UnboundLocalError
      +-- OSError
      |    +-- BlockingIOError
      |    +-- ChildProcessError
      |    +-- ConnectionError
      |    |    +-- BrokenPipeError
      |    |    +-- ConnectionAbortedError
      |    |    +-- ConnectionRefusedError
      |    |    +-- ConnectionResetError
      |    +-- FileExistsError
      |    +-- FileNotFoundError
      |    +-- InterruptedError
      |    +-- IsADirectoryError
      |    +-- NotADirectoryError
      |    +-- PermissionError
      |    +-- ProcessLookupError
      |    +-- TimeoutError
      +-- ReferenceError
      +-- RuntimeError
      |    +-- NotImplementedError
      |    +-- RecursionError
      +-- SyntaxError
      |    +-- IndentationError
      |         +-- TabError
      +-- SystemError
      +-- TypeError
      +-- ValueError
      |    +-- UnicodeError
      |         +-- UnicodeDecodeError
      |         +-- UnicodeEncodeError
      |         +-- UnicodeTranslateError
      +-- Warning
           +-- DeprecationWarning
           +-- PendingDeprecationWarning
           +-- RuntimeWarning
           +-- SyntaxWarning
           +-- UserWarning
           +-- FutureWarning
           +-- ImportWarning
           +-- UnicodeWarning
           +-- BytesWarning
           +-- ResourceWarning

Don’t Do this

If you’re using this form of exception handling:

try:
    something
except: # don't just do a bare except!
    pass

Then you won’t be able to interrupt your something block with Ctrl-C. Your program will overlook every possible Exception inside the try code block.

Here’s another example that will have the same undesirable behavior:

except BaseException as e: # don't do this either - same as bare!
    logging.info(e)

Instead, try to only catch the specific exception you know you’re looking for. For example, if you know you might get a value-error on a conversion:

try:
    foo = operation_that_includes_int(foo)
except ValueError as e:
    if fatal_condition(): # You can raise the exception if it's bad,
        logging.info(e)   # but if it's fatal every time,
        raise             # you probably should just not catch it.
    else:                 # Only catch exceptions you are prepared to handle.
        foo = 0           # Here we simply assign foo to 0 and continue. 

Further Explanation with another example

You might be doing it because you’ve been web-scraping and been getting say, a UnicodeError, but because you’ve used the broadest Exception catching, your code, which may have other fundamental flaws, will attempt to run to completion, wasting bandwidth, processing time, wear and tear on your equipment, running out of memory, collecting garbage data, etc.

If other people are asking you to complete so that they can rely on your code, I understand feeling compelled to just handle everything. But if you’re willing to fail noisily as you develop, you will have the opportunity to correct problems that might only pop up intermittently, but that would be long term costly bugs.

With more precise error handling, you code can be more robust.


回答 4

>>> import this

提姆·彼得斯(Tim Peters)撰写的《 Python之禅》

美丽胜于丑陋。
显式胜于隐式。
简单胜于复杂。
复杂胜于复杂。
扁平比嵌套更好。
稀疏胜于密集。
可读性很重要。
特殊情况还不足以打破规则。
尽管实用性胜过纯度。
错误绝不能默默传递。
除非明确地保持沉默。
面对模棱两可的想法,拒绝猜测的诱惑。
应该有一种-最好只有一种-显而易见的方法。
尽管除非您是荷兰人,否则一开始这种方式可能并不明显。
现在总比没有好。
虽然从来没有比这更好正确的现在。
如果实现难以解释,那是个坏主意。
如果实现易于解释,则可能是个好主意。
命名空间是一个很棒的主意-让我们做更多这些吧!

所以,这是我的看法。每当发现错误时,都应该采取措施进行处理,即将其写入日志文件或其他内容。至少,它通知您以前曾经有错误。

>>> import this

The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren’t special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one– and preferably only one –obvious way to do it.
Although that way may not be obvious at first unless you’re Dutch.
Now is better than never.
Although never is often better than right now.
If the implementation is hard to explain, it’s a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea — let’s do more of those!

So, here is my opinion. Whenever you find an error, you should do something to handle it, i.e. write it in logfile or something else. At least, it informs you that there used to be a error.


回答 5

您至少except Exception:应避免捕获诸如SystemExit或的系统异常KeyboardInterrupt。这里是文档链接

通常,应明确定义要捕获的异常,以避免捕获不需要的异常。您应该知道忽略了哪些异常。

You should use at least except Exception: to avoid catching system exceptions like SystemExit or KeyboardInterrupt. Here’s link to docs.

In general you should define explicitly exceptions you want to catch, to avoid catching unwanted exceptions. You should know what exceptions you ignore.


回答 6

首先,它违反了Python Zen的两个原则:

  • 显式胜于隐式
  • 错误绝不能默默传递

这意味着您故意使错误静默地通过。而且,您不知道确切发生了哪个错误,因为except: pass它将捕获任何异常。

其次,如果我们试图从Python的Zen中抽象出来,并以理智的眼光说话,您应该知道,使用except:pass会使您在系统中没有知识和控制力。经验法则是在发生错误时引发异常,并采取适当的措施。如果您事先不知道该怎么做,请至少将错误记录在某个地方(并最好重新引发该异常):

try:
    something
except:
    logger.exception('Something happened')

但是,通常,如果您尝试捕获任何异常,则可能是在做错什么!

First, it violates two principles of Zen of Python:

  • Explicit is better than implicit
  • Errors should never pass silently

What it means, is that you intentionally make your error pass silently. Moreover, you don’t event know, which error exactly occurred, because except: pass will catch any exception.

Second, if we try to abstract away from the Zen of Python, and speak in term of just sanity, you should know, that using except:pass leaves you with no knowledge and control in your system. The rule of thumb is to raise an exception, if error happens, and take appropriate actions. If you don’t know in advance, what actions these should be, at least log the error somewhere (and better re-raise the exception):

try:
    something
except:
    logger.exception('Something happened')

But, usually, if you try to catch any exception, you are probably doing something wrong!


回答 7

except:pass构造实质上使在代码中涵盖的代码出现时出现的所有异常情况保持沉默。try:在运行块中。

造成这种不良习惯的原因在于,通常这并不是您真正想要的。更常见的情况是,您想沉默一些特定的情况,并且except:pass这实在是一种过时的工具。它可以完成工作,但也可以掩盖您可能未曾预料到的其他错误情况,但很可能希望以其他方式处理。

在Python中这一点尤其重要的是,通过这种语言的习惯用法,异常不一定是error。当然,就像大多数语言一样,通常也以这种方式使用它们。但是特别是Python偶尔会使用它们来实现一些代码任务的替代退出路径,这实际上并不是正常运行情况的一部分,但仍然不时出现,并且在大多数情况下甚至可以预期。SystemExit已经作为一个旧示例被提及,但是如今最常见的示例可能是StopIteration。这种使用异常的方式引起了很多争议,尤其是在迭代器和生成器首次引入Python时,但最终这个想法盛行。

The except:pass construct essentially silences any and all exceptional conditions that come up while the code covered in the try: block is being run.

What makes this bad practice is that it usually isn’t what you really want. More often, some specific condition is coming up that you want to silence, and except:pass is too much of a blunt instrument. It will get the job done, but it will also mask other error conditions that you likely haven’t anticipated, but may very well want to deal with in some other way.

What makes this particularly important in Python is that by the idioms of this language, exceptions are not necessarily errors. They’re often used this way, of course, just as in most languages. But Python in particular has occasionally used them to implement an alternative exit path from some code tasks which isn’t really part of the normal running case, but is still known to come up from time to time and may even be expected in most cases. SystemExit has already been mentioned as an old example, but the most common example nowadays may be StopIteration. Using exceptions this way caused a lot of controversy, especially when iterators and generators were first introduced to Python, but eventually the idea prevailed.


回答 8

已经说明了#1原因-它隐藏了您没有想到的错误。

(#2)- 它使您的代码难以被他人阅读和理解。如果在尝试读取文件时捕获到FileNotFoundException,那么对于另一个开发人员而言,“ catch”块应具有的功能非常明显。如果未指定异常,则需要附加注释以说明该块应执行的操作。

(#3)- 演示了惰性编程。如果使用通用的try / catch,则表明您不了解程序中可能出现的运行时错误,或者您不知道Python中可能出现的异常。捕获特定错误表明您既了解程序又了解Python引发的错误范围。这更有可能使其他开发人员和代码审阅者信任您的工作。

The #1 reason has already been stated – it hides errors that you did not expect.

(#2) – It makes your code difficult for others to read and understand. If you catch a FileNotFoundException when you are trying to read a file, then it is pretty obvious to another developer what functionality the ‘catch’ block should have. If you do not specify an exception, then you need additional commenting to explain what the block should do.

(#3) – It demonstrates lazy programming. If you use the generic try/catch, it indicates either that you do not understand the possible run-time errors in your program, or that you do not know what exceptions are possible in Python. Catching a specific error shows that you understand both your program and the range of errors that Python throws. This is more likely to make other developers and code-reviewers trust your work.


回答 9

那么,此代码产生什么输出?

fruits = [ 'apple', 'pear', 'carrot', 'banana' ]

found = False
try:
     for i in range(len(fruit)):
         if fruits[i] == 'apple':
             found = true
except:
     pass

if found:
    print "Found an apple"
else:
    print "No apples in list"

现在,假设tryexcept块是对复杂对象层次结构的数百行调用,它本身在大型程序的调用树中间被调用。当程序出错时,您从哪里开始寻找?

So, what output does this code produce?

fruits = [ 'apple', 'pear', 'carrot', 'banana' ]

found = False
try:
     for i in range(len(fruit)):
         if fruits[i] == 'apple':
             found = true
except:
     pass

if found:
    print "Found an apple"
else:
    print "No apples in list"

Now imagine the tryexcept block is hundreds of lines of calls to a complex object hierarchy, and is itself called in the middle of large program’s call tree. When the program goes wrong, where do you start looking?


回答 10

通常,您可以将任何错误/异常分为以下三种类别之一

  • 致命的:不是您的错,您无法阻止它们,也无法从中恢复。您当然不应该忽略它们并继续运行,并使程序保持未知状态。只要让错误终止您的程序,您就无能为力了。

  • 骨头:您自己的错误,很可能是由于疏忽,错误或编程错误所致。您应该修复该错误。同样,您当然应该不忽略并继续。

  • 外生的:在特殊情况下(例如找不到文件连接终止),您可能会遇到这些错误。您应该明确地处理这些错误,并且仅处理这些错误。

在任何情况下,except: pass都只会使程序处于未知状态,在这种状态下可能会造成更大的破坏。

In general, you can classify any error/exception in one of three categories:

  • Fatal: Not your fault, you cannot prevent them, you cannot recover from them. You should certainly not ignore them and continue, and leave your program in an unknown state. Just let the error terminate your program, there is nothing you can do.

  • Boneheaded: Your own fault, most likely due to an oversight, bug or programming error. You should fix the bug. Again, you should most certainly not ignore and continue.

  • Exogenous: You can expect these errors in exceptional situations, such as file not found or connection terminated. You should explicitly handle these errors, and only these.

In all cases except: pass will only leave your program in an unknown state, where it can cause more damage.


回答 11

简而言之,如果引发异常或错误,则说明存在问题。可能不是很不对劲,但是仅仅为了使用goto语句而创建,抛出和捕获错误和异常并不是一个好主意,而且很少这样做。99%的时间,某处出现问题。

需要解决的问题。就像生活中的情况一样,在编程中,如果您只是将问题搁置一旁并尝试忽略它们,那么它们就不会多次自行消失。相反,它们变得更大并成倍增加。为防止问题在您身上蔓延并进一步打击您,您可以1)消除它,然后清理残局,或者2)遏制它,然后清理残局。

只是忽略异常和错误并让它们像那样,是体验内存泄漏,出色的数据库连接,不必要的文件权限锁定等的好方法。

在极少数情况下,问题是如此的微小,琐碎,并且-除了需要try … catch块之外- 自包含的,以至于事后确实没有任何需要清理的地方。在这些情况下,这些最佳做法不一定适用。以我的经验,这通常意味着代码所做的任何事情基本上都是小巧的和可忽略的,而重试尝试或特殊消息之类的东西既不值得其复杂性也不值得其坚持下去。

在我公司,规则是几乎总是在某个陷阱中做某事,如果您什么都不做,那么您必须始终以非常充分的理由发表评论。要做任何事情时,您绝不能通过或留空捕获块。

Simply put, if an exception or error is thrown, something’s wrong. It may not be something very wrong, but creating, throwing, and catching errors and exceptions just for the sake of using goto statements is not a good idea, and it’s rarely done. 99% of the time, there was a problem somewhere.

Problems need to be dealt with. Just like how it is in life, in programming, if you just leave problems alone and try to ignore them, they don’t just go away on their own a lot of times; instead they get bigger and multiply. To prevent a problem from growing on you and striking again further down the road, you either 1) eliminate it and clean up the mess afterwards, or 2) contain it and clean up the mess afterwards.

Just ignoring exceptions and errors and leaving them be like that is a good way to experience memory leaks, outstanding database connections, needless locks on file permissions, etc.

On rare occasions, the problem is so miniscule, trivial, and – aside from needing a try…catch block – self-contained, that there really is just no mess to be cleaned up afterwards. These are the only occasions when this best practice doesn’t necessarily apply. In my experience, this has generally meant that whatever the code is doing is basically petty and forgoable, and something like retry attempts or special messages are worth neither the complexity nor holding the thread up on.

At my company, the rule is to almost always do something in a catch block, and if you don’t do anything, then you must always place a comment with a very good reason why not. You must never pass or leave an empty catch block when there is anything to be done.


回答 12

在我看来,错误是有原因出现的,我的声音很愚蠢,但这就是事实。良好的编程仅在必须处理错误时才会引发错误。另外,正如我前段时间所读到的,“ pass-Statement是一个显示代码的语句将在以后插入”,因此,如果您想拥有一个空的except-statement,可以随意这样做,但是对于一个好的程序,成为一部分。因为你不处理你应该拥有的东西。出现的异常使您有机会更正输入数据或更改数据结构,因此这些异常不会再次发生(但是在大多数情况下(网络异常,常规输入异常),异常表明程序的下一部分将无法正常执行。例如,NetworkException可能指示网络连接断开,并且该程序无法在接下来的程序步骤中发送/接收数据。

但是仅对一个执行块使用pass块是有效的,因为您仍然区分异常类型,因此,如果将所有异常块放在一个中,则它不是空的:

try:
    #code here
except Error1:
    #exception handle1

except Error2:
    #exception handle2
#and so on

可以这样重写:

try:
    #code here
except BaseException as e:
    if isinstance(e, Error1):
        #exception handle1

    elif isinstance(e, Error2):
        #exception handle2

    ...

    else:
        raise

因此,即使是多个带有通过语句的except-block也会导致代码,其代码可处理特殊类型的异常。

In my opinion errors have a reason to appear, that my sound stupid, but thats the way it is. Good programming only raises errors when you have to handle them. Also, as i read some time ago, “the pass-Statement is a Statement that Shows code will be inserted later”, so if you want to have an empty except-statement feel free to do so, but for a good program there will be a part missing. because you dont handle the things you should have. Appearing exceptions give you the chance to correct input data or to change your data structure so these exceptions dont occur again (but in most cases (Network-exceptions, General input-exceptions) exceptions indicate that the next parts of the program wont execute well. For example a NetworkException can indicate a broken network-connection and the program cant send/recieve data in the next program steps.

But using a pass block for only one execption-block is valid, because you still differenciate beetween the types of exceptions, so if you put all exception-blocks in one, it is not empty:

try:
    #code here
except Error1:
    #exception handle1

except Error2:
    #exception handle2
#and so on

can be rewritten that way:

try:
    #code here
except BaseException as e:
    if isinstance(e, Error1):
        #exception handle1

    elif isinstance(e, Error2):
        #exception handle2

    ...

    else:
        raise

So even multiple except-blocks with pass-statements can result in code, whose structure handles special types of exceptions.


回答 13

到目前为止提出的所有评论均有效。在可能的情况下,您需要指定要忽略的异常。在可能的情况下,您需要分析导致异常的原因,只忽略您要忽略的内容,而不要忽略其余的内容。如果异常导致应用程序“严重崩溃”,那么就这样吧,因为比起掩盖曾经发生过的问题,了解意外事件在发生时更为重要。

综上所述,不要以任何编程实践为重。真傻 总是有时间和地点进行忽略所有exceptions的阻止。

愚蠢至高无上的另一个例子是goto运算符的用法。当我在学校的时候,我们的教授教我们goto操作员,只是提起您永远不要使用它。不要相信有人告诉您xyz永远不要使用,并且在任何情况下都不会有用。总有。

All comments brought up so far are valid. Where possible you need to specify what exactly exception you want to ignore. Where possible you need to analyze what caused exception, and only ignore what you meant to ignore, and not the rest. If exception causes application to “crash spectacularly”, then be it, because it’s much more important to know the unexpected happened when it happened, than concealing that the problem ever occurred.

With all that said, do not take any programming practice as a paramount. This is stupid. There always is the time and place to do ignore-all-exceptions block.

Another example of idiotic paramount is usage of goto operator. When I was in school, our professor taught us goto operator just to mention that thou shalt not use it, EVER. Don’t believe people telling you that xyz should never be used and there cannot be a scenario when it is useful. There always is.


回答 14

错误处理在编程中非常重要。您确实需要向用户显示出了什么问题。在极少数情况下,您可以忽略这些错误。这是非常糟糕的编程习惯。

​Handling errors is very important in programming. You do need to show the user what went wrong. In very few cases you can ignore the errors. This is it is very bad programming practice.


回答 15

由于尚未提及,因此使用更好的样式contextlib.suppress

with suppress(FileNotFoundError):
    os.remove('somefile.tmp')

请注意,在提供的示例中, ,无论是否发生异常程序状态均保持不变。也就是说,somefile.tmp总是不存在。

Since it hasn’t been mentioned yet, it’s better style to use contextlib.suppress:

with suppress(FileNotFoundError):
    os.remove('somefile.tmp')

Notice that in the example provided, the program state remains the same, whether or not the exception occurs. That is to say, somefile.tmp always becomes non-existent.


“ is None”和“ == None”有什么区别?

问题:“ is None”和“ == None”有什么区别?

我最近遇到了这种语法,我不知道有什么区别。

如果有人可以告诉我与众不同,我将不胜感激。

I recently came across this syntax, I am unaware of the difference.

I would appreciate it if someone could tell me the difference.


回答 0

答案在这里解释。

报价:

一个类可以自由选择以任何方式实现比较,并且可以选择与None进行比较意味着某种意义(这实际上是有道理的;如果有人告诉您从头开始实现None对象,那么您将如何获得它来比较True?反对自己?)。

实际上,由于自定义比较运算符很少见,因此差异不大。但是您应该使用is None一般规则。

The answer is explained here.

To quote:

A class is free to implement comparison any way it chooses, and it can choose to make comparison against None mean something (which actually makes sense; if someone told you to implement the None object from scratch, how else would you get it to compare True against itself?).

Practically-speaking, there is not much difference since custom comparison operators are rare. But you should use is None as a general rule.


回答 1

class Foo:
    def __eq__(self,other):
        return True
foo=Foo()

print(foo==None)
# True

print(foo is None)
# False
class Foo:
    def __eq__(self,other):
        return True
foo=Foo()

print(foo==None)
# True

print(foo is None)
# False

回答 2

在这种情况下,它们是相同的。None是单例对象(只有一个存在None)。

is 检查对象是否是同一对象,而==只是检查它们是否等效。

例如:

p = [1]
q = [1]
p is q # False because they are not the same actual object
p == q # True because they are equivalent

但是由于只有一个None,它们将始终相同,is并将返回True。

p = None
q = None
p is q # True because they are both pointing to the same "None"

In this case, they are the same. None is a singleton object (there only ever exists one None).

is checks to see if the object is the same object, while == just checks if they are equivalent.

For example:

p = [1]
q = [1]
p is q # False because they are not the same actual object
p == q # True because they are equivalent

But since there is only one None, they will always be the same, and is will return True.

p = None
q = None
p is q # True because they are both pointing to the same "None"

回答 3

如果您使用numpy,

if np.zeros(3)==None: pass

numpy进行元素比较时会给你错误

If you use numpy,

if np.zeros(3)==None: pass

will give you error when numpy does elementwise comparison


回答 4

这取决于您要与“无”进行比较。一些类具有自定义比较方法,这些方法与== None区别对待is None

特别是的输出a == None 甚至不必是布尔值!-错误的常见原因。

对于特定示例,请使用numpy数组,其中==逐元素实现比较:

import numpy as np
a = np.zeros(3) # now a is array([0., 0., 0.])
a == None #compares elementwise, outputs array([False, False, False]), i.e. not boolean!!!
a is None #compares object to object, outputs False

It depends on what you are comparing to None. Some classes have custom comparison methods that treat == None differently from is None.

In particular the output of a == None does not even have to be boolean !! – a frequent cause of bugs.

For a specific example take a numpy array where the == comparison is implemented elementwise:

import numpy as np
a = np.zeros(3) # now a is array([0., 0., 0.])
a == None #compares elementwise, outputs array([False, False, False]), i.e. not boolean!!!
a is None #compares object to object, outputs False

将目录永久添加到PYTHONPATH?

问题:将目录永久添加到PYTHONPATH?

每当我使用时sys.path.append,都会添加新目录。但是,一旦我关闭python,列表将恢复为以前的值(默认值)。如何将目录永久添加到PYTHONPATH

Whenever I use sys.path.append, the new directory will be added. However, once I close python, the list will revert to the previous (default?) values. How do I permanently add a directory to PYTHONPATH?


回答 0

您需要将新目录添加到环境变量中PYTHONPATH,并用冒号与其之前的内容分隔开。在任何形式的Unix中,您都可以在启动脚本中执行此操作,该脚本适合于您正在使用的任何shell(.profile或取决于您喜欢的shell),该命令又取决于所讨论的shell。在Windows中,您可以为此目的通过系统GUI进行操作。

superuser.com 可能是一个更好的地方,例如,如果您需要有关如何在所选平台和外壳程序中丰富环境变量的详细信息,请提供更多详细信息,因为这本身并不是真正的编程问题。

You need to add your new directory to the environment variable PYTHONPATH, separated by a colon from previous contents thereof. In any form of Unix, you can do that in a startup script appropriate to whatever shell you’re using (.profile or whatever, depending on your favorite shell) with a command which, again, depends on the shell in question; in Windows, you can do it through the system GUI for the purpose.

superuser.com may be a better place to ask further, i.e. for more details if you need specifics about how to enrich an environment variable in your chosen platform and shell, since it’s not really a programming question per se.


回答 1

如果您正在使用bash(在Mac或GNU / Linux发行版上),请将其添加到您的 ~/.bashrc

export PYTHONPATH="${PYTHONPATH}:/my/other/path"

If you’re using bash (on a Mac or GNU/Linux distro), add this to your ~/.bashrc

export PYTHONPATH="${PYTHONPATH}:/my/other/path"

回答 2

除了操作之外,PYTHONPATH您还可以创建路径配置文件。首先找出Python在哪个目录中搜索此信息:

python -m site --user-site

由于某些原因,这似乎在Python 2.7中不起作用。在那里您可以使用:

python -c 'import site; site._script()' --user-site

然后.pth在该目录中创建一个文件,其中包含您要添加的路径(如果目录不存在,则创建该目录)。

例如:

# find directory
SITEDIR=$(python -m site --user-site)

# create if it doesn't exist
mkdir -p "$SITEDIR"

# create new .pth file with our path
echo "$HOME/foo/bar" > "$SITEDIR/somelib.pth"

Instead of manipulating PYTHONPATH you can also create a path configuration file. First find out in which directory Python searches for this information:

python -m site --user-site

For some reason this doesn’t seem to work in Python 2.7. There you can use:

python -c 'import site; site._script()' --user-site

Then create a .pth file in that directory containing the path you want to add (create the directory if it doesn’t exist).

For example:

# find directory
SITEDIR=$(python -m site --user-site)

# create if it doesn't exist
mkdir -p "$SITEDIR"

# create new .pth file with our path
echo "$HOME/foo/bar" > "$SITEDIR/somelib.pth"

回答 3

这适用于Windows

  1. 在Windows上,对于Python 2.7,请转到Python设置文件夹。
  2. 打开库/站点包。
  3. 将example.pth空文件添加到此文件夹。
  4. 将所需的路径添加到文件,每行一个。

然后,您将能够从脚本中查看这些路径内的所有模块。

This works on Windows

  1. On Windows, with Python 2.7 go to the Python setup folder.
  2. Open Lib/site-packages.
  3. Add an example.pth empty file to this folder.
  4. Add the required path to the file, one per each line.

Then you’ll be able to see all modules within those paths from your scripts.


回答 4

如果仍然有人困惑-如果您使用的是Mac,请执行以下操作:

  1. 打开终端
  2. 类型 open .bash_profile
  3. 在弹出的文本文件中,在最后添加以下行: export PYTHONPATH=$PYTHONPATH:foo/bar
  4. 保存文件,重新启动终端,然后完成

In case anyone is still confused – if you are on a Mac, do the following:

  1. Open up Terminal
  2. Type open .bash_profile
  3. In the text file that pops up, add this line at the end: export PYTHONPATH=$PYTHONPATH:foo/bar
  4. Save the file, restart the Terminal, and you’re done

回答 5

您可以通过pythonrc文件添加路径,该文件在Linux上默认为〜/ .pythonrc。即。

import sys
sys.path.append('/path/to/dir')

您也可以PYTHONPATH在全局rc文件中(例如~/.profile在Mac或Linux上)或通过Windows上的“控制面板”->“系统”->“高级”选项卡->“环境变量”来设置环境变量。

You could add the path via your pythonrc file, which defaults to ~/.pythonrc on linux. ie.

import sys
sys.path.append('/path/to/dir')

You could also set the PYTHONPATH environment variable, in a global rc file, such ~/.profile on mac or linux, or via Control Panel -> System -> Advanced tab -> Environment Variables on windows.


回答 6

为了提供更多说明,Python将使用脚本(通常位于sys.prefix + 和中)自动构建其搜索路径(如上所述此处)。一个可以获得sys.prefix的值:site.pylib/python<version>/site-packageslib/site-python

python -c 'import sys; print(sys.prefix)'

然后,site.py脚本将取决于平台的许多目录(例如/usr/{lib,share}/python<version>/dist-packages)添加/usr/local/lib/python<version>/dist-packages到搜索路径,并且还在这些路径中<package>.pth搜索包含特定其他搜索路径的配置文件。例如,easy-install维护其已安装软件包的集合,这些软件包已添加到系统特定文件中,例如在Ubuntu上/usr/local/lib/python2.7/dist-packages/easy-install.pth。在典型的系统上,有很多这些.pth文件,它们可以解释sys.path中一些意外的路径:

python -c 'import sys; print(sys.path)'

因此,可以创建一个.pth文件并将其放置在任何这些目录中(包括如上所述的sitedir )。这似乎是大多数软件包被添加到sys.path的方式,而不是使用PYTHONPATH。

注意:在OSX上,site.py为’framework builds’添加了一个特殊的附加搜索路径(但似乎适用于python的常规命令行使用):(/Library/Python/<version>/site-packages例如,对于Python2.7:)/Library/Python/2.7/site-packages/,这是应该使用第三方软件包的地方要安装(请参阅该目录中的自述文件)。因此,可以在其中添加包含其他搜索路径的路径配置文件,例如创建一个名为的文件/Library/Python/2.7/site-packages/pip-usr-local.pth,其中包含/usr/local/lib/python2.7/site-packages/,然后系统python将添加该搜索路径。

To give a bit more explanation, Python will automatically construct its search paths (as mentioned above and here) using the site.py script (typically located in sys.prefix + lib/python<version>/site-packages as well as lib/site-python). One can obtain the value of sys.prefix:

python -c 'import sys; print(sys.prefix)'

The site.py script then adds a number of directories, dependent upon the platform, such as /usr/{lib,share}/python<version>/dist-packages, /usr/local/lib/python<version>/dist-packages to the search path and also searches these paths for <package>.pth config files which contain specific additional search paths. For example easy-install maintains its collection of installed packages which are added to a system specific file e.g on Ubuntu it’s /usr/local/lib/python2.7/dist-packages/easy-install.pth. On a typical system there are a bunch of these .pth files around which can explain some unexpected paths in sys.path:

python -c 'import sys; print(sys.path)'

So one can create a .pth file and put in any of these directories (including the sitedir as mentioned above). This seems to be the way most packages get added to the sys.path as opposed to using the PYTHONPATH.

Note: On OSX there’s a special additional search path added by site.py for ‘framework builds’ (but seems to work for normal command line use of python): /Library/Python/<version>/site-packages (e.g. for Python2.7: /Library/Python/2.7/site-packages/) which is where 3rd party packages are supposed to be installed (see the README in that dir). So one can add a path configuration file in there containing additional search paths e.g. create a file called /Library/Python/2.7/site-packages/pip-usr-local.pth which contains /usr/local/lib/python2.7/site-packages/ and then the system python will add that search path.


回答 7

对我来说,当我更改.bash_profile文件时它起作用了。只是更改.bashrc文件才有效,直到我重新启动外壳程序为止。

对于python 2.7,它应如下所示:

export PYTHONPATH="$PYTHONPATH:/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python"

.bash_profile文件末尾。

For me it worked when I changed the .bash_profile file. Just changing .bashrc file worked only till I restarted the shell.

For python 2.7 it should look like:

export PYTHONPATH="$PYTHONPATH:/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python"

at the end of the .bash_profile file.


回答 8

在Linux上,您可以创建从软件包到PYTHONPATH目录的符号链接,而不必处理环境变量。就像是:

ln -s /your/path /usr/lib/pymodules/python2.7/

On linux you can create a symbolic link from your package to a directory of the PYTHONPATH without having to deal with the environment variables. Something like:

ln -s /your/path /usr/lib/pymodules/python2.7/

回答 9

export PYTHONPATH="${PYTHONPATH}:/my/other/path"如果PYTHONPATH当前不存在,则添加到〜/ .bashrc可能不起作用(因为:)。

export PYTHONPATH="/my/other/path1"
export PYTHONPATH="${PYTHONPATH}:/my/other/path2"

将以上内容添加到我的〜/ .bashrc中可以在Ubuntu 16.04上为我实现窍门

Adding export PYTHONPATH="${PYTHONPATH}:/my/other/path" to the ~/.bashrc might not work if PYTHONPATH does not currently exist (because of the :).

export PYTHONPATH="/my/other/path1"
export PYTHONPATH="${PYTHONPATH}:/my/other/path2"

Adding the above to my ~/.bashrc did the trick for me on Ubuntu 16.04


回答 10

在MacOS上,而不是提供到特定库的路径。提供到根项目文件夹的完整路径

~/.bash_profile 

让我过得愉快,例如:

export PYTHONPATH="${PYTHONPATH}:/Users/<myuser>/project_root_folder_path"

在此之后:

source ~/.bash_profile

On MacOS, Instead of giving path to a specific library. Giving full path to the root project folder in

~/.bash_profile 

made my day, for example:

export PYTHONPATH="${PYTHONPATH}:/Users/<myuser>/project_root_folder_path"

after this do:

source ~/.bash_profile

回答 11

只是对awesomo的答案添加,也可以添加该行到您~/.bash_profile~/.profile

Just to add on awesomo’s answer, you can also add that line into your ~/.bash_profile or ~/.profile


回答 12

通过以下方式手动添加到PYTHONPATH的新路径:

在终端中通过以下方式将路径添加到〜/ .bashrc配置文件中:

vim ~/.bashrc

将以下内容粘贴到您的个人资料中

export PYTHONPATH="${PYTHONPATH}:/User/johndoe/pythonModule"

然后,确保在终端中运行代码时都获取bashrc配置文件的来源:

source ~/.bashrc 

希望这可以帮助。

The add a new path to PYTHONPATH is doing in manually by:

adding the path to your ~/.bashrc profile, in terminal by:

vim ~/.bashrc

paste the following to your profile

export PYTHONPATH="${PYTHONPATH}:/User/johndoe/pythonModule"

then, make sure to source your bashrc profile when ever you run your code in terminal:

source ~/.bashrc 

Hope this helps.


回答 13

我在Windows Vista中永久添加了Python 3.5

系统>控制面板>高级系统设置>高级(点击)环境变量>系统变量>(如果在“变量”列中没有看到PYTHONPATH)(单击)新建>变量名称:PYTHONPATH>变量值:

请在变量值中写入目录。这是Blue Peppers答案的细节。

I added permanently in Windows Vista, Python 3.5

System > Control Panel > Advanced system settings > Advanced (tap) Environment Variables > System variables > (if you don’t see PYTHONPATH in Variable column) (click) New > Variable name: PYTHONPATH > Variable value:

Please, write the directory in the Variable value. It is details of Blue Peppers’ answer.


回答 14

以下脚本是纯Python,因此可在所有平台上使用。它利用了https://docs.python.org/3/library/pathlib.html此处记录的pathlib路径,以使其跨平台工作。您只需运行一次,然后重新启动内核即可。受https://medium.com/@arnaud.bertrand/modifying-python-s-search-path-with-pth-files-2a41a4143574的启发。

from pathlib import Path
to_add=Path(path_of_directory_to_add)
from sys import path

if str(to_add) not in path:
    minLen=999999
    for index,directory in enumerate(path):
        if 'site-packages' in directory and len(directory)<=minLen:
            minLen=len(directory)
            stpi=index

    pathSitePckgs=Path(path[stpi])
    with open(str(pathSitePckgs/'current_machine_paths.pth'),'w') as pth_file:
        pth_file.write(str(to_add))

The script below works on all platforms as it’s pure Python. It makes use of the pathlib Path, documented here https://docs.python.org/3/library/pathlib.html, to make it work cross-platform. You run it once, restart the kernel and that’s it. Inspired by https://medium.com/@arnaud.bertrand/modifying-python-s-search-path-with-pth-files-2a41a4143574.

from pathlib import Path
to_add=Path(path_of_directory_to_add)
from sys import path

if str(to_add) not in path:
    minLen=999999
    for index,directory in enumerate(path):
        if 'site-packages' in directory and len(directory)<=minLen:
            minLen=len(directory)
            stpi=index

    pathSitePckgs=Path(path[stpi])
    with open(str(pathSitePckgs/'current_machine_paths.pth'),'w') as pth_file:
        pth_file.write(str(to_add))

回答 15

这是对此线程的更新,具有一些旧的答案。

对于使用MAC-OS Catalina或更高版本(> = 10.15)的用户,它引入了一个新的终端,名为zsh(替代旧的bash)。

由于此更改,上述答案有些问题,我通过创建文件~/.zshrc并将文件目录粘贴到$PATH和进行了一些变通方法$PYTHONPATH

所以,首先我做了:

nano ~/.zshrc

当编辑器打开时,我粘贴了以下内容:

export PATH="${PATH}:/Users/caio.hc.oliveira/Library/Python/3.7/bin"
export PYTHONPATH="${PYTHONPATH}:/Users/caio.hc.oliveira/Library/Python/3.7/bin"

保存它,然后重新启动终端。

重要提示:上面的路径设置为我计算机的路径,您必须将其调整为适合您的python。

This is an update to this thread which has some old answers.

For those using MAC-OS Catalina or some newer (>= 10.15), it was introduced a new Terminal named zsh (a substitute to the old bash).

I had some problems with the answers above due to this change, and I somewhat did a workaround by creating the file ~/.zshrc and pasting the file directory to the $PATH and $PYTHONPATH

So, first I did:

nano ~/.zshrc

When the editor opened I pasted the following content:

export PATH="${PATH}:/Users/caio.hc.oliveira/Library/Python/3.7/bin"
export PYTHONPATH="${PYTHONPATH}:/Users/caio.hc.oliveira/Library/Python/3.7/bin"

saved it, and restarted the terminal.

IMPORTANT: The path above is set to my computer’s path, you would have to adapt it to your python.


回答 16

在Python 3.6.4中,您可以像这样在python会话之间持久化sys.path:

import sys
import os

print(str(sys.path))

dir_path = os.path.dirname(os.path.realpath(__file__))
print(f"current working dir: {dir_path}")

root_dir = dir_path.replace("/util", '', 1)
print(f"root dir: {root_dir}")

sys.path.insert(0, root_dir)

print(str(sys.path))

我强烈建议您使用virtualenv和virtualenvwrapper,否则您的路径将会混乱

In Python 3.6.4 you can persist sys.path across python sessions like this:

import sys
import os

print(str(sys.path))

dir_path = os.path.dirname(os.path.realpath(__file__))
print(f"current working dir: {dir_path}")

root_dir = dir_path.replace("/util", '', 1)
print(f"root dir: {root_dir}")

sys.path.insert(0, root_dir)

print(str(sys.path))

I strongly suggest you use virtualenv and virtualenvwrapper otherwise you will clutter your path


回答 17

A <-> B之间的最短路径是一条直线;

import sys
if not 'NEW_PATH' in sys.path:
  sys.path += ['NEW_PATH']

Shortest path between A <-> B is a straight line;

import sys
if not 'NEW_PATH' in sys.path:
  sys.path += ['NEW_PATH']

“太多的价值无法解包”,遍历一个字典。键=>字符串,值=>列表

问题:“太多的价值无法解包”,遍历一个字典。键=>字符串,值=>列表

我得到了'too many values to unpack'错误。知道我该如何解决吗?

first_names = ['foo', 'bar']
last_names = ['gravy', 'snowman']

fields = {
    'first_names': first_names,
    'last_name': last_names,
}        

for field, possible_values in fields:  # error happens on this line              

I am getting the 'too many values to unpack' error. Any idea how I can fix this?

first_names = ['foo', 'bar']
last_names = ['gravy', 'snowman']

fields = {
    'first_names': first_names,
    'last_name': last_names,
}        

for field, possible_values in fields:  # error happens on this line              

回答 0

Python 2

您需要使用iteritems

for field, possible_values in fields.iteritems():
    print field, possible_values

请参阅此答案,以获取有关遍历字典的更多信息,例如items()在python版本之间使用using 。

Python 3

由于Python 3的 iteritems()不再支持。使用items()代替。

for field, possible_values in fields.items():
    print(field, possible_values)

Python 2

You need to use something like iteritems.

for field, possible_values in fields.iteritems():
    print field, possible_values

See this answer for more information on iterating through dictionaries, such as using items(), across python versions.

Python 3

Since Python 3 iteritems() is no longer supported. Use items() instead.

for field, possible_values in fields.items():
    print(field, possible_values)

回答 1

对于Python 3.x iteritems,已删除。改用物品

for field, possible_values in fields.items():
    print(field, possible_values)

For Python 3.x iteritems has been removed. Use items instead.

for field, possible_values in fields.items():
    print(field, possible_values)

回答 2

您要使用iteritems。这将在字典上返回一个迭代器,从而为您提供一个元组(键,值)

>>> for field, values in fields.iteritems():
...     print field, values
... 
first_names ['foo', 'bar']
last_name ['gravy', 'snowman']

您的问题是您正在遍历字段,该字段返回字典的键。

>>> for field in fields:
...     print field
... 
first_names
last_name

You want to use iteritems. This returns an iterator over the dictionary, which gives you a tuple(key, value)

>>> for field, values in fields.iteritems():
...     print field, values
... 
first_names ['foo', 'bar']
last_name ['gravy', 'snowman']

Your problem was that you were looping over fields, which returns the keys of the dictionary.

>>> for field in fields:
...     print field
... 
first_names
last_name

回答 3

对于列表,使用 enumerate

for field, possible_values in enumerate(fields):
    print(field, possible_values)

iteritems 不适用于列表对象

For lists, use enumerate

for field, possible_values in enumerate(fields):
    print(field, possible_values)

iteritems will not work for list objects


回答 4

在Python3 iteritems()中不再受支持

解决方案1

采用 .items

for field, possible_values in fields.items():
    print(field, possible_values)

解决方案2

您可以使用enumerate(),以及

for field, possible_values in enumerate(fields):
    print(field, possible_values)

In Python3 iteritems() is no longer supported

SOLUTION1:

Use .items

for field, possible_values in fields.items():
    print(field, possible_values)

SOLUTION2:

You can use enumerate() as well

for field, possible_values in enumerate(fields):
    print(field, possible_values)

回答 5

不能直接在字典中进行迭代。这样就可以通过转换为元组了

first_names = ['foo', 'bar']
last_names = ['gravy', 'snowman']

fields = {
    'first_names': first_names,
    'last_name': last_names,
         } 
tup_field=tuple(fields.items())
for names in fields.items():
     field,possible_values = names
     tup_possible_values=tuple(possible_values)
     for pvalue in tup_possible_values:
           print (field + "is" + pvalue)

Can’t be iterating directly in dictionary. So you can through converting into tuple.

first_names = ['foo', 'bar']
last_names = ['gravy', 'snowman']

fields = {
    'first_names': first_names,
    'last_name': last_names,
         } 
tup_field=tuple(fields.items())
for names in fields.items():
     field,possible_values = names
     tup_possible_values=tuple(possible_values)
     for pvalue in tup_possible_values:
           print (field + "is" + pvalue)

回答 6

fields.iteritems()在代码中丢失了。

您也可以采用其他方式,即使用字典中的键获取值。

for key in fields:
    value = fields[key]

you are missing fields.iteritems() in your code.

You could also do it other way, where you get values using keys in the dictionary.

for key in fields:
    value = fields[key]

回答 7

data = (['President','George','Bush','is','.'],['O','B-PERSON','I-PERSON','O','O'])
corpus = []
for(doc,tags) in data:
    doc_tag = []
    for word,tag in zip(doc,tags):
        doc_tag.append((word,tag))
        corpus.append(doc_tag)
        print(corpus)
data = (['President','George','Bush','is','.'],['O','B-PERSON','I-PERSON','O','O'])
corpus = []
for(doc,tags) in data:
    doc_tag = []
    for word,tag in zip(doc,tags):
        doc_tag.append((word,tag))
        corpus.append(doc_tag)
        print(corpus)

如何查看文件中的更改?

问题:如何查看文件中的更改?

我有一个日志文件正在由另一个进程写入,我想监视它的更改。每次发生更改时,我都希望读入新数据以对其进行一些处理。

最好的方法是什么?我希望从PyWin32库中获得某种吸引。我找到了该win32file.FindNextChangeNotification功能,但不知道如何要求它观看特定文件。

如果有人做了这样的事情,我将不胜感激。

[编辑]我应该提到我在寻求不需要轮询的解决方案。

[编辑]诅咒!看来这在映射的网络驱动器上不起作用。我猜想Windows不会像在本地磁盘上那样“听到”文件的任何更新。

I have a log file being written by another process which I want to watch for changes. Each time a change occurs I’d like to read the new data in to do some processing on it.

What’s the best way to do this? I was hoping there’d be some sort of hook from the PyWin32 library. I’ve found the win32file.FindNextChangeNotification function but have no idea how to ask it to watch a specific file.

If anyone’s done anything like this I’d be really grateful to hear how…

[Edit] I should have mentioned that I was after a solution that doesn’t require polling.

[Edit] Curses! It seems this doesn’t work over a mapped network drive. I’m guessing windows doesn’t ‘hear’ any updates to the file the way it does on a local disk.


回答 0

您是否已经看过http://timgolden.me.uk/python/win32_how_do_i/watch_directory_for_changes.html上的可用文档?如果只需要它在Windows下运行,则第二个示例似乎正是您想要的(如果您将目录的路径与要观看的文件之一交换了)。

否则,轮询将可能是唯一真正与平台无关的选项。

注意:我还没有尝试过任何这些解决方案。

Have you already looked at the documentation available on http://timgolden.me.uk/python/win32_how_do_i/watch_directory_for_changes.html? If you only need it to work under Windows the 2nd example seems to be exactly what you want (if you exchange the path of the directory with the one of the file you want to watch).

Otherwise, polling will probably be the only really platform-independent option.

Note: I haven’t tried any of these solutions.


回答 1

您尝试使用看门狗了吗?

Python API库和Shell实用程序可监视文件系统事件。

目录监视变得容易

  • 跨平台API。
  • 一种外壳程序工具,用于响应目录更改而运行命令。

通过快速入门中的一个简单示例快速入门

Did you try using Watchdog?

Python API library and shell utilities to monitor file system events.

Directory monitoring made easy with

  • A cross-platform API.
  • A shell tool to run commands in response to directory changes.

Get started quickly with a simple example in Quickstart


回答 2

如果轮询对您来说足够好,那么我只看“修改时间”文件的统计信息是否发生了变化。阅读:

os.stat(filename).st_mtime

(还要注意,Windows本机更改事件解决方案并非在所有情况下(例如在网络驱动器上)都适用。)

import os

class Monkey(object):
    def __init__(self):
        self._cached_stamp = 0
        self.filename = '/path/to/file'

    def ook(self):
        stamp = os.stat(self.filename).st_mtime
        if stamp != self._cached_stamp:
            self._cached_stamp = stamp
            # File has changed, so do something...

If polling is good enough for you, I’d just watch if the “modified time” file stat changes. To read it:

os.stat(filename).st_mtime

(Also note that the Windows native change event solution does not work in all circumstances, e.g. on network drives.)

import os

class Monkey(object):
    def __init__(self):
        self._cached_stamp = 0
        self.filename = '/path/to/file'

    def ook(self):
        stamp = os.stat(self.filename).st_mtime
        if stamp != self._cached_stamp:
            self._cached_stamp = stamp
            # File has changed, so do something...

回答 3

如果您需要多平台解决方案,请检查QFileSystemWatcher。这里是一个示例代码(未清除):

from PyQt4 import QtCore

@QtCore.pyqtSlot(str)
def directory_changed(path):
    print('Directory Changed!!!')

@QtCore.pyqtSlot(str)
def file_changed(path):
    print('File Changed!!!')

fs_watcher = QtCore.QFileSystemWatcher(['/path/to/files_1', '/path/to/files_2', '/path/to/files_3'])

fs_watcher.connect(fs_watcher, QtCore.SIGNAL('directoryChanged(QString)'), directory_changed)
fs_watcher.connect(fs_watcher, QtCore.SIGNAL('fileChanged(QString)'), file_changed)

If you want a multiplatform solution, then check QFileSystemWatcher. Here an example code (not sanitized):

from PyQt4 import QtCore

@QtCore.pyqtSlot(str)
def directory_changed(path):
    print('Directory Changed!!!')

@QtCore.pyqtSlot(str)
def file_changed(path):
    print('File Changed!!!')

fs_watcher = QtCore.QFileSystemWatcher(['/path/to/files_1', '/path/to/files_2', '/path/to/files_3'])

fs_watcher.connect(fs_watcher, QtCore.SIGNAL('directoryChanged(QString)'), directory_changed)
fs_watcher.connect(fs_watcher, QtCore.SIGNAL('fileChanged(QString)'), file_changed)

回答 4

它不能在Windows上运行(也许使用cygwin吗?),但是对于Unix用户,您应该使用“ fcntl”系统调用。这是Python中的示例。如果您需要用C编写(相同的函数名称),则几乎是相同的代码

import time
import fcntl
import os
import signal

FNAME = "/HOME/TOTO/FILETOWATCH"

def handler(signum, frame):
    print "File %s modified" % (FNAME,)

signal.signal(signal.SIGIO, handler)
fd = os.open(FNAME,  os.O_RDONLY)
fcntl.fcntl(fd, fcntl.F_SETSIG, 0)
fcntl.fcntl(fd, fcntl.F_NOTIFY,
            fcntl.DN_MODIFY | fcntl.DN_CREATE | fcntl.DN_MULTISHOT)

while True:
    time.sleep(10000)

It should not work on windows (maybe with cygwin ?), but for unix user, you should use the “fcntl” system call. Here is an example in Python. It’s mostly the same code if you need to write it in C (same function names)

import time
import fcntl
import os
import signal

FNAME = "/HOME/TOTO/FILETOWATCH"

def handler(signum, frame):
    print "File %s modified" % (FNAME,)

signal.signal(signal.SIGIO, handler)
fd = os.open(FNAME,  os.O_RDONLY)
fcntl.fcntl(fd, fcntl.F_SETSIG, 0)
fcntl.fcntl(fd, fcntl.F_NOTIFY,
            fcntl.DN_MODIFY | fcntl.DN_CREATE | fcntl.DN_MULTISHOT)

while True:
    time.sleep(10000)

回答 5

查看pyinotify

inotify在较新的linux中替换了dnotify(来自较早的答案),并允许文件级而不是目录级的监视。

Check out pyinotify.

inotify replaces dnotify (from an earlier answer) in newer linuxes and allows file-level rather than directory-level monitoring.


回答 6

在对Tim Golden的脚本进行了一些修改之后,我发现以下内容似乎运行良好:

import os

import win32file
import win32con

path_to_watch = "." # look at the current directory
file_to_watch = "test.txt" # look for changes to a file called test.txt

def ProcessNewData( newData ):
    print "Text added: %s"%newData

# Set up the bits we'll need for output
ACTIONS = {
  1 : "Created",
  2 : "Deleted",
  3 : "Updated",
  4 : "Renamed from something",
  5 : "Renamed to something"
}
FILE_LIST_DIRECTORY = 0x0001
hDir = win32file.CreateFile (
  path_to_watch,
  FILE_LIST_DIRECTORY,
  win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE,
  None,
  win32con.OPEN_EXISTING,
  win32con.FILE_FLAG_BACKUP_SEMANTICS,
  None
)

# Open the file we're interested in
a = open(file_to_watch, "r")

# Throw away any exising log data
a.read()

# Wait for new data and call ProcessNewData for each new chunk that's written
while 1:
  # Wait for a change to occur
  results = win32file.ReadDirectoryChangesW (
    hDir,
    1024,
    False,
    win32con.FILE_NOTIFY_CHANGE_LAST_WRITE,
    None,
    None
  )

  # For each change, check to see if it's updating the file we're interested in
  for action, file in results:
    full_filename = os.path.join (path_to_watch, file)
    #print file, ACTIONS.get (action, "Unknown")
    if file == file_to_watch:
        newText = a.read()
        if newText != "":
            ProcessNewData( newText )

它可能可以处理更多的错误检查,但是对于简单地查看日志文件并在将其吐到屏幕上之前对其进行一些处理,这很好。

感谢大家的投入-很棒的东西!

Well after a bit of hacking of Tim Golden’s script, I have the following which seems to work quite well:

import os

import win32file
import win32con

path_to_watch = "." # look at the current directory
file_to_watch = "test.txt" # look for changes to a file called test.txt

def ProcessNewData( newData ):
    print "Text added: %s"%newData

# Set up the bits we'll need for output
ACTIONS = {
  1 : "Created",
  2 : "Deleted",
  3 : "Updated",
  4 : "Renamed from something",
  5 : "Renamed to something"
}
FILE_LIST_DIRECTORY = 0x0001
hDir = win32file.CreateFile (
  path_to_watch,
  FILE_LIST_DIRECTORY,
  win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE,
  None,
  win32con.OPEN_EXISTING,
  win32con.FILE_FLAG_BACKUP_SEMANTICS,
  None
)

# Open the file we're interested in
a = open(file_to_watch, "r")

# Throw away any exising log data
a.read()

# Wait for new data and call ProcessNewData for each new chunk that's written
while 1:
  # Wait for a change to occur
  results = win32file.ReadDirectoryChangesW (
    hDir,
    1024,
    False,
    win32con.FILE_NOTIFY_CHANGE_LAST_WRITE,
    None,
    None
  )

  # For each change, check to see if it's updating the file we're interested in
  for action, file in results:
    full_filename = os.path.join (path_to_watch, file)
    #print file, ACTIONS.get (action, "Unknown")
    if file == file_to_watch:
        newText = a.read()
        if newText != "":
            ProcessNewData( newText )

It could probably do with a load more error checking, but for simply watching a log file and doing some processing on it before spitting it out to the screen, this works well.

Thanks everyone for your input – great stuff!


回答 7

为了观看具有轮询和最小依赖性的单个文件,下面是一个基于Deestan(上图)的答案的充实示例:

import os
import sys 
import time

class Watcher(object):
    running = True
    refresh_delay_secs = 1

    # Constructor
    def __init__(self, watch_file, call_func_on_change=None, *args, **kwargs):
        self._cached_stamp = 0
        self.filename = watch_file
        self.call_func_on_change = call_func_on_change
        self.args = args
        self.kwargs = kwargs

    # Look for changes
    def look(self):
        stamp = os.stat(self.filename).st_mtime
        if stamp != self._cached_stamp:
            self._cached_stamp = stamp
            # File has changed, so do something...
            print('File changed')
            if self.call_func_on_change is not None:
                self.call_func_on_change(*self.args, **self.kwargs)

    # Keep watching in a loop        
    def watch(self):
        while self.running: 
            try: 
                # Look for changes
                time.sleep(self.refresh_delay_secs) 
                self.look() 
            except KeyboardInterrupt: 
                print('\nDone') 
                break 
            except FileNotFoundError:
                # Action on file not found
                pass
            except: 
                print('Unhandled error: %s' % sys.exc_info()[0])

# Call this function each time a change happens
def custom_action(text):
    print(text)

watch_file = 'my_file.txt'

# watcher = Watcher(watch_file)  # simple
watcher = Watcher(watch_file, custom_action, text='yes, changed')  # also call custom action function
watcher.watch()  # start the watch going

For watching a single file with polling, and minimal dependencies, here is a fully fleshed-out example, based on answer from Deestan (above):

import os
import sys 
import time

class Watcher(object):
    running = True
    refresh_delay_secs = 1

    # Constructor
    def __init__(self, watch_file, call_func_on_change=None, *args, **kwargs):
        self._cached_stamp = 0
        self.filename = watch_file
        self.call_func_on_change = call_func_on_change
        self.args = args
        self.kwargs = kwargs

    # Look for changes
    def look(self):
        stamp = os.stat(self.filename).st_mtime
        if stamp != self._cached_stamp:
            self._cached_stamp = stamp
            # File has changed, so do something...
            print('File changed')
            if self.call_func_on_change is not None:
                self.call_func_on_change(*self.args, **self.kwargs)

    # Keep watching in a loop        
    def watch(self):
        while self.running: 
            try: 
                # Look for changes
                time.sleep(self.refresh_delay_secs) 
                self.look() 
            except KeyboardInterrupt: 
                print('\nDone') 
                break 
            except FileNotFoundError:
                # Action on file not found
                pass
            except: 
                print('Unhandled error: %s' % sys.exc_info()[0])

# Call this function each time a change happens
def custom_action(text):
    print(text)

watch_file = 'my_file.txt'

# watcher = Watcher(watch_file)  # simple
watcher = Watcher(watch_file, custom_action, text='yes, changed')  # also call custom action function
watcher.watch()  # start the watch going

回答 8

检查类似问题的回答。您可以在Python中尝试相同的循环。该页面建议:

import time

while 1:
    where = file.tell()
    line = file.readline()
    if not line:
        time.sleep(1)
        file.seek(where)
    else:
        print line, # already has newline

另请参见问题tail()使用Python的文件

Check my answer to a similar question. You could try the same loop in Python. This page suggests:

import time

while 1:
    where = file.tell()
    line = file.readline()
    if not line:
        time.sleep(1)
        file.seek(where)
    else:
        print line, # already has newline

Also see the question tail() a file with Python.


回答 9

对我来说,最简单的解决方案是使用看门狗工具watchmedo

现在从https://pypi.python.org/pypi/watchdog获得一个进程,该进程可以查找目录中的sql文件,并在必要时执行它们。

watchmedo shell-command \
--patterns="*.sql" \
--recursive \
--command='~/Desktop/load_files_into_mysql_database.sh' \
.

Simplest solution for me is using watchdog’s tool watchmedo

From https://pypi.python.org/pypi/watchdog I now have a process that looks up the sql files in a directory and executes them if necessary.

watchmedo shell-command \
--patterns="*.sql" \
--recursive \
--command='~/Desktop/load_files_into_mysql_database.sh' \
.

回答 10

好吧,由于您使用的是Python,因此您可以打开一个文件并继续读取其中的行。

f = open('file.log')

如果读取的行不为空,则对其进行处理。

line = f.readline()
if line:
    // Do what you want with the line

您可能会错过继续拨打readlineEOF的权限。在这种情况下,它将仅返回一个空字符串。并且,将某些内容添加到日志文件后,将根据需要从停止的位置继续读取。

如果您正在寻找使用事件或特定库的解决方案,请在问题中进行指定。否则,我认为这种解决方案就可以了。

Well, since you are using Python, you can just open a file and keep reading lines from it.

f = open('file.log')

If the line read is not empty, you process it.

line = f.readline()
if line:
    // Do what you want with the line

You may be missing that it is ok to keep calling readline at the EOF. It will just keep returning an empty string in this case. And when something is appended to the log file, the reading will continue from where it stopped, as you need.

If you are looking for a solution that uses events, or a particular library, please specify this in your question. Otherwise, I think this solution is just fine.


回答 11

这是Kender代码的简化版本,看起来可以起到相同的作用,并且不会导入整个文件:

# Check file for new data.

import time

f = open(r'c:\temp\test.txt', 'r')

while True:

    line = f.readline()
    if not line:
        time.sleep(1)
        print 'Nothing New'
    else:
        print 'Call Function: ', line

Here is a simplified version of Kender’s code that appears to do the same trick and does not import the entire file:

# Check file for new data.

import time

f = open(r'c:\temp\test.txt', 'r')

while True:

    line = f.readline()
    if not line:
        time.sleep(1)
        print 'Nothing New'
    else:
        print 'Call Function: ', line

回答 12

这是Tim Goldan脚本的另一种修改,该脚本可在unix类型上运行,并通过使用dict(file => time)添加了一个简单的文件修改监视程序。

用法:whateverName.py path_to_dir_to_watch

#!/usr/bin/env python

import os, sys, time

def files_to_timestamp(path):
    files = [os.path.join(path, f) for f in os.listdir(path)]
    return dict ([(f, os.path.getmtime(f)) for f in files])

if __name__ == "__main__":

    path_to_watch = sys.argv[1]
    print('Watching {}..'.format(path_to_watch))

    before = files_to_timestamp(path_to_watch)

    while 1:
        time.sleep (2)
        after = files_to_timestamp(path_to_watch)

        added = [f for f in after.keys() if not f in before.keys()]
        removed = [f for f in before.keys() if not f in after.keys()]
        modified = []

        for f in before.keys():
            if not f in removed:
                if os.path.getmtime(f) != before.get(f):
                    modified.append(f)

        if added: print('Added: {}'.format(', '.join(added)))
        if removed: print('Removed: {}'.format(', '.join(removed)))
        if modified: print('Modified: {}'.format(', '.join(modified)))

        before = after

This is another modification of Tim Goldan’s script that runs on unix types and adds a simple watcher for file modification by using a dict (file=>time).

usage: whateverName.py path_to_dir_to_watch

#!/usr/bin/env python

import os, sys, time

def files_to_timestamp(path):
    files = [os.path.join(path, f) for f in os.listdir(path)]
    return dict ([(f, os.path.getmtime(f)) for f in files])

if __name__ == "__main__":

    path_to_watch = sys.argv[1]
    print('Watching {}..'.format(path_to_watch))

    before = files_to_timestamp(path_to_watch)

    while 1:
        time.sleep (2)
        after = files_to_timestamp(path_to_watch)

        added = [f for f in after.keys() if not f in before.keys()]
        removed = [f for f in before.keys() if not f in after.keys()]
        modified = []

        for f in before.keys():
            if not f in removed:
                if os.path.getmtime(f) != before.get(f):
                    modified.append(f)

        if added: print('Added: {}'.format(', '.join(added)))
        if removed: print('Removed: {}'.format(', '.join(removed)))
        if modified: print('Modified: {}'.format(', '.join(modified)))

        before = after

回答 13

正如您在由Horst Gutmann指出的Tim Golden的文章中所看到,WIN32比较复杂,并且监视目录,而不是单个文件。

我想建议您研究IronPython,它是一个.NET python实现。借助IronPython,您可以使用所有.NET功能-包括

System.IO.FileSystemWatcher

使用简单的事件接口处理单个文件。

As you can see in Tim Golden’s article, pointed by Horst Gutmann, WIN32 is relatively complex and watches directories, not a single file.

I’d like to suggest you look into IronPython, which is a .NET python implementation. With IronPython you can use all the .NET functionality – including

System.IO.FileSystemWatcher

Which handles single files with a simple Event interface.


回答 14

这是检查文件更改的示例。这样做可能不是最好的方法,但是肯定是很短的方法。

对源进行更改后重新启动应用程序的便捷工具。我在使用pygame玩游戏时做到了这一点,因此我可以看到文件保存后立即发生了效果。

在pygame中使用时,请确保“ while”循环中的内容已放置在您的游戏循环中,也称为update或其他内容。否则,您的应用程序将陷入无限循环,并且您将看不到游戏更新。

file_size_stored = os.stat('neuron.py').st_size

  while True:
    try:
      file_size_current = os.stat('neuron.py').st_size
      if file_size_stored != file_size_current:
        restart_program()
    except: 
      pass

如果您想要我在网上找到的重启代码。这里是。(与问题无关,尽管可以派上用场)

def restart_program(): #restart application
    python = sys.executable
    os.execl(python, python, * sys.argv)

让电子做您想做的事情变得有趣。

This is an example of checking a file for changes. One that may not be the best way of doing it, but it sure is a short way.

Handy tool for restarting application when changes have been made to the source. I made this when playing with pygame so I can see effects take place immediately after file save.

When used in pygame make sure the stuff in the ‘while’ loop is placed in your game loop aka update or whatever. Otherwise your application will get stuck in an infinite loop and you will not see your game updating.

file_size_stored = os.stat('neuron.py').st_size

  while True:
    try:
      file_size_current = os.stat('neuron.py').st_size
      if file_size_stored != file_size_current:
        restart_program()
    except: 
      pass

In case you wanted the restart code which I found on the web. Here it is. (Not relevant to the question, though it could come in handy)

def restart_program(): #restart application
    python = sys.executable
    os.execl(python, python, * sys.argv)

Have fun making electrons do what you want them to do.


回答 15

ACTIONS = {
  1 : "Created",
  2 : "Deleted",
  3 : "Updated",
  4 : "Renamed from something",
  5 : "Renamed to something"
}
FILE_LIST_DIRECTORY = 0x0001

class myThread (threading.Thread):
    def __init__(self, threadID, fileName, directory, origin):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.fileName = fileName
        self.daemon = True
        self.dir = directory
        self.originalFile = origin
    def run(self):
        startMonitor(self.fileName, self.dir, self.originalFile)

def startMonitor(fileMonitoring,dirPath,originalFile):
    hDir = win32file.CreateFile (
        dirPath,
        FILE_LIST_DIRECTORY,
        win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE,
        None,
        win32con.OPEN_EXISTING,
        win32con.FILE_FLAG_BACKUP_SEMANTICS,
        None
    )
    # Wait for new data and call ProcessNewData for each new chunk that's
    # written
    while 1:
        # Wait for a change to occur
        results = win32file.ReadDirectoryChangesW (
            hDir,
            1024,
            False,
            win32con.FILE_NOTIFY_CHANGE_LAST_WRITE,
            None,
            None
        )
        # For each change, check to see if it's updating the file we're
        # interested in
        for action, file_M in results:
            full_filename = os.path.join (dirPath, file_M)
            #print file, ACTIONS.get (action, "Unknown")
            if len(full_filename) == len(fileMonitoring) and action == 3:
                #copy to main file
                ...
ACTIONS = {
  1 : "Created",
  2 : "Deleted",
  3 : "Updated",
  4 : "Renamed from something",
  5 : "Renamed to something"
}
FILE_LIST_DIRECTORY = 0x0001

class myThread (threading.Thread):
    def __init__(self, threadID, fileName, directory, origin):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.fileName = fileName
        self.daemon = True
        self.dir = directory
        self.originalFile = origin
    def run(self):
        startMonitor(self.fileName, self.dir, self.originalFile)

def startMonitor(fileMonitoring,dirPath,originalFile):
    hDir = win32file.CreateFile (
        dirPath,
        FILE_LIST_DIRECTORY,
        win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE,
        None,
        win32con.OPEN_EXISTING,
        win32con.FILE_FLAG_BACKUP_SEMANTICS,
        None
    )
    # Wait for new data and call ProcessNewData for each new chunk that's
    # written
    while 1:
        # Wait for a change to occur
        results = win32file.ReadDirectoryChangesW (
            hDir,
            1024,
            False,
            win32con.FILE_NOTIFY_CHANGE_LAST_WRITE,
            None,
            None
        )
        # For each change, check to see if it's updating the file we're
        # interested in
        for action, file_M in results:
            full_filename = os.path.join (dirPath, file_M)
            #print file, ACTIONS.get (action, "Unknown")
            if len(full_filename) == len(fileMonitoring) and action == 3:
                #copy to main file
                ...

回答 16

这是一个示例,用于观察每秒写入不超过一行但通常少得多的输入文件。目标是将最后一行(最新写入)追加到指定的输出文件。我已从我的一个项目中复制了此内容,并删除了所有不相关的行。您必须填写或更改缺少的符号。

from PyQt5.QtCore import QFileSystemWatcher, QSettings, QThread
from ui_main_window import Ui_MainWindow   # Qt Creator gen'd 

class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        Ui_MainWindow.__init__(self)
        self._fileWatcher = QFileSystemWatcher()
        self._fileWatcher.fileChanged.connect(self.fileChanged)

    def fileChanged(self, filepath):
        QThread.msleep(300)    # Reqd on some machines, give chance for write to complete
        # ^^ About to test this, may need more sophisticated solution
        with open(filepath) as file:
            lastLine = list(file)[-1]
        destPath = self._filemap[filepath]['dest file']
        with open(destPath, 'a') as out_file:               # a= append
            out_file.writelines([lastLine])

当然,并不是严格要求包含QMainWindow类。您可以单独使用QFileSystemWatcher。

Here’s an example geared toward watching input files that write no more than one line per second but usually a lot less. The goal is to append the last line (most recent write) to the specified output file. I’ve copied this from one of my projects and just deleted all the irrelevant lines. You’ll have to fill in or change the missing symbols.

from PyQt5.QtCore import QFileSystemWatcher, QSettings, QThread
from ui_main_window import Ui_MainWindow   # Qt Creator gen'd 

class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        Ui_MainWindow.__init__(self)
        self._fileWatcher = QFileSystemWatcher()
        self._fileWatcher.fileChanged.connect(self.fileChanged)

    def fileChanged(self, filepath):
        QThread.msleep(300)    # Reqd on some machines, give chance for write to complete
        # ^^ About to test this, may need more sophisticated solution
        with open(filepath) as file:
            lastLine = list(file)[-1]
        destPath = self._filemap[filepath]['dest file']
        with open(destPath, 'a') as out_file:               # a= append
            out_file.writelines([lastLine])

Of course, the encompassing QMainWindow class is not strictly required, ie. you can use QFileSystemWatcher alone.


回答 17

您还可以使用一个名为repyt的简单库,这是一个示例:

repyt ./app.py

You can also use a simple library called repyt, here is an example:

repyt ./app.py

回答 18

似乎没有人发布fswatch。它是一个跨平台的文件系统监视程序。只需安装,运行并按照提示进行操作即可。

我已经将它与python和golang程序一起使用,并且可以正常工作。

Seems that no one has posted fswatch. It is a cross-platform file system watcher. Just install it, run it and follow the prompts.

I’ve used it with python and golang programs and it just works.


回答 19

相关的@ 4Oh4解决方案可以平滑地更改要查看的文件列表;

import os
import sys
import time

class Watcher(object):
    running = True
    refresh_delay_secs = 1

    # Constructor
    def __init__(self, watch_files, call_func_on_change=None, *args, **kwargs):
        self._cached_stamp = 0
        self._cached_stamp_files = {}
        self.filenames = watch_files
        self.call_func_on_change = call_func_on_change
        self.args = args
        self.kwargs = kwargs

    # Look for changes
    def look(self):
        for file in self.filenames:
            stamp = os.stat(file).st_mtime
            if not file in self._cached_stamp_files:
                self._cached_stamp_files[file] = 0
            if stamp != self._cached_stamp_files[file]:
                self._cached_stamp_files[file] = stamp
                # File has changed, so do something...
                file_to_read = open(file, 'r')
                value = file_to_read.read()
                print("value from file", value)
                file_to_read.seek(0)
                if self.call_func_on_change is not None:
                    self.call_func_on_change(*self.args, **self.kwargs)

    # Keep watching in a loop
    def watch(self):
        while self.running:
            try:
                # Look for changes
                time.sleep(self.refresh_delay_secs)
                self.look()
            except KeyboardInterrupt:
                print('\nDone')
                break
            except FileNotFoundError:
                # Action on file not found
                pass
            except Exception as e:
                print(e)
                print('Unhandled error: %s' % sys.exc_info()[0])

# Call this function each time a change happens
def custom_action(text):
    print(text)
    # pass

watch_files = ['/Users/mexekanez/my_file.txt', '/Users/mexekanez/my_file1.txt']

# watcher = Watcher(watch_file)  # simple



if __name__ == "__main__":
    watcher = Watcher(watch_files, custom_action, text='yes, changed')  # also call custom action function
    watcher.watch()  # start the watch going

related @4Oh4 solution a smooth change for a list of files to watch;

import os
import sys
import time

class Watcher(object):
    running = True
    refresh_delay_secs = 1

    # Constructor
    def __init__(self, watch_files, call_func_on_change=None, *args, **kwargs):
        self._cached_stamp = 0
        self._cached_stamp_files = {}
        self.filenames = watch_files
        self.call_func_on_change = call_func_on_change
        self.args = args
        self.kwargs = kwargs

    # Look for changes
    def look(self):
        for file in self.filenames:
            stamp = os.stat(file).st_mtime
            if not file in self._cached_stamp_files:
                self._cached_stamp_files[file] = 0
            if stamp != self._cached_stamp_files[file]:
                self._cached_stamp_files[file] = stamp
                # File has changed, so do something...
                file_to_read = open(file, 'r')
                value = file_to_read.read()
                print("value from file", value)
                file_to_read.seek(0)
                if self.call_func_on_change is not None:
                    self.call_func_on_change(*self.args, **self.kwargs)

    # Keep watching in a loop
    def watch(self):
        while self.running:
            try:
                # Look for changes
                time.sleep(self.refresh_delay_secs)
                self.look()
            except KeyboardInterrupt:
                print('\nDone')
                break
            except FileNotFoundError:
                # Action on file not found
                pass
            except Exception as e:
                print(e)
                print('Unhandled error: %s' % sys.exc_info()[0])

# Call this function each time a change happens
def custom_action(text):
    print(text)
    # pass

watch_files = ['/Users/mexekanez/my_file.txt', '/Users/mexekanez/my_file1.txt']

# watcher = Watcher(watch_file)  # simple



if __name__ == "__main__":
    watcher = Watcher(watch_files, custom_action, text='yes, changed')  # also call custom action function
    watcher.watch()  # start the watch going

回答 20

最好和最简单的解决方案是使用pygtail:https ://pypi.python.org/pypi/pygtail

from pygtail import Pygtail
import sys

while True:
    for line in Pygtail("some.log"):
        sys.stdout.write(line)

The best and simplest solution is to use pygtail: https://pypi.python.org/pypi/pygtail

from pygtail import Pygtail
import sys

while True:
    for line in Pygtail("some.log"):
        sys.stdout.write(line)

回答 21

我不知道Windows的任何特定功能。您可以尝试每秒钟/分钟/小时获取文件的MD5哈希值(取决于您需要的速度),并将其与最后一个哈希值进行比较。如果不同,您就知道文件已更改,并读出了最新的行。

I don’t know any Windows specific function. You could try getting the MD5 hash of the file every second/minute/hour (depends on how fast you need it) and compare it to the last hash. When it differs you know the file has been changed and you read out the newest lines.


回答 22

我会尝试这样的事情。

    try:
            f = open(filePath)
    except IOError:
            print "No such file: %s" % filePath
            raw_input("Press Enter to close window")
    try:
            lines = f.readlines()
            while True:
                    line = f.readline()
                    try:
                            if not line:
                                    time.sleep(1)
                            else:
                                    functionThatAnalisesTheLine(line)
                    except Exception, e:
                            # handle the exception somehow (for example, log the trace) and raise the same exception again
                            raw_input("Press Enter to close window")
                            raise e
    finally:
            f.close()

循环检查自上次读取文件以来是否存在新行-如果存在,则将其读取并传递给functionThatAnalisesTheLine函数。如果不是,脚本将等待1秒钟,然后重试该过程。

I’d try something like this.

    try:
            f = open(filePath)
    except IOError:
            print "No such file: %s" % filePath
            raw_input("Press Enter to close window")
    try:
            lines = f.readlines()
            while True:
                    line = f.readline()
                    try:
                            if not line:
                                    time.sleep(1)
                            else:
                                    functionThatAnalisesTheLine(line)
                    except Exception, e:
                            # handle the exception somehow (for example, log the trace) and raise the same exception again
                            raw_input("Press Enter to close window")
                            raise e
    finally:
            f.close()

The loop checks if there is a new line(s) since last time file was read – if there is, it’s read and passed to the functionThatAnalisesTheLine function. If not, script waits 1 second and retries the process.


如何使用matplotlib.pyplot更改图例大小

问题:如何使用matplotlib.pyplot更改图例大小

这里有一个简单的问题:我试图使用matplotlib.pyplot较小的图例(即,文本较小)。我正在使用的代码是这样的:

plot.figure()
plot.scatter(k, sum_cf, color='black', label='Sum of Cause Fractions')
plot.scatter(k, data[:, 0],  color='b', label='Dis 1: cf = .6, var = .2')
plot.scatter(k, data[:, 1],  color='r',  label='Dis 2: cf = .2, var = .1')
plot.scatter(k, data[:, 2],  color='g', label='Dis 3: cf = .1, var = .01')
plot.legend(loc=2)

Simple question here: I’m trying to get the size of my legend using matplotlib.pyplot to be smaller (i.e., the text to be smaller). The code I’m using goes something like this:

plot.figure()
plot.scatter(k, sum_cf, color='black', label='Sum of Cause Fractions')
plot.scatter(k, data[:, 0],  color='b', label='Dis 1: cf = .6, var = .2')
plot.scatter(k, data[:, 1],  color='r',  label='Dis 2: cf = .2, var = .1')
plot.scatter(k, data[:, 2],  color='g', label='Dis 3: cf = .1, var = .01')
plot.legend(loc=2)

回答 0

您可以通过调整prop关键字为图例设置单独的字体大小。

plot.legend(loc=2, prop={'size': 6})

这需要对应于matplotlib.font_manager.FontProperties属性的关键字字典。请参阅说明文件的文档

关键字参数:

prop: [ None | FontProperties | dict ]
    A matplotlib.font_manager.FontProperties instance. If prop is a 
    dictionary, a new instance will be created with prop. If None, use
    rc settings.

1.2.1版开始,也可以使用关键字fontsize

You can set an individual font size for the legend by adjusting the prop keyword.

plot.legend(loc=2, prop={'size': 6})

This takes a dictionary of keywords corresponding to matplotlib.font_manager.FontProperties properties. See the documentation for legend:

Keyword arguments:

prop: [ None | FontProperties | dict ]
    A matplotlib.font_manager.FontProperties instance. If prop is a 
    dictionary, a new instance will be created with prop. If None, use
    rc settings.

It is also possible, as of version 1.2.1, to use the keyword fontsize.


回答 1

这应该做

import pylab as plot
params = {'legend.fontsize': 20,
          'legend.handlelength': 2}
plot.rcParams.update(params)

然后再做图。

还有很多其他rcParam,它们也可以在matplotlibrc文件中设置。

大概还可以通过matplotlib.font_manager.FontProperties实例更改它,但是我不知道该怎么做。->请参阅Yann的答案。

This should do

import pylab as plot
params = {'legend.fontsize': 20,
          'legend.handlelength': 2}
plot.rcParams.update(params)

Then do the plot afterwards.

There are a ton of other rcParams, they can also be set in the matplotlibrc file.

Also presumably you can change it passing a matplotlib.font_manager.FontProperties instance but this I don’t know how to do. –> see Yann’s answer.


回答 2

使用 import matplotlib.pyplot as plt

方法1:调用图例时指定字体大小(重复)

plt.legend(fontsize=20) # using a size in points
plt.legend(fontsize="x-large") # using a named size

使用此方法,您可以在创建时为每个图例设置字体大小(允许您拥有多个具有不同字体大小的图例)。但是,每次创建图例时,都必须手动键入所有内容。

(注意:@ Mathias711在他的答案中列出了可用的命名字体大小)

方法2:在rcParams中指定字体大小(方便)

plt.rc('legend',fontsize=20) # using a size in points
plt.rc('legend',fontsize='medium') # using a named size

使用此方法,您可以设置默认的图例字体大小,除非使用方法1另行指定,否则所有图例将自动使用该字体。这意味着您可以在代码开头设置图例字体大小,而不必担心为每个图例设置它。

如果你使用了一个名为大小例如'medium',那么传说中的文本将与全球规模font.sizercParams。改变font.size用途plt.rc(font.size='medium')

using import matplotlib.pyplot as plt

Method 1: specify the fontsize when calling legend (repetitive)

plt.legend(fontsize=20) # using a size in points
plt.legend(fontsize="x-large") # using a named size

With this method you can set the fontsize for each legend at creation (allowing you to have multiple legends with different fontsizes). However, you will have to type everything manually each time you create a legend.

(Note: @Mathias711 listed the available named fontsizes in his answer)

Method 2: specify the fontsize in rcParams (convenient)

plt.rc('legend',fontsize=20) # using a size in points
plt.rc('legend',fontsize='medium') # using a named size

With this method you set the default legend fontsize, and all legends will automatically use that unless you specify otherwise using method 1. This means you can set your legend fontsize at the beginning of your code, and not worry about setting it for each individual legend.

If you use a named size e.g. 'medium', then the legend text will scale with the global font.size in rcParams. To change font.size use plt.rc(font.size='medium')


回答 3

除了点的大小,还有一些命名的fontsizes

xx-small
x-small
small
medium
large
x-large
xx-large

用法:

pyplot.legend(loc=2, fontsize = 'x-small')

There are also a few named fontsizes, apart from the size in points:

xx-small
x-small
small
medium
large
x-large
xx-large

Usage:

pyplot.legend(loc=2, fontsize = 'x-small')

回答 4

有多种设置可用于调整图例大小。我发现最有用的两个是:

  • labelspacing:以字体大小的倍数设置标签条目之间的间距。例如使用10磅字体,legend(..., labelspacing=0.2)会将条目之间的间距减少到2点。我安装的默认值约为0.5。
  • prop:可以完全控制字体大小等。您可以使用设置8点字体legend(..., prop={'size':8})。我安装的默认值约为14点。

此外,图例的文档列出了许多其他填充的和间隔的参数,包括:borderpadhandlelengthhandletextpadborderaxespad,和columnspacing。这些都遵循相同的格式,与labelspacing和area相同,也是fontsize的倍数。

也可以使用matplotlibrc文件将这些值设置为所有图形的默认值。

There are multiple settings for adjusting the legend size. The two I find most useful are:

  • labelspacing: which sets the spacing between label entries in multiples of the font size. For instance with a 10 point font, legend(..., labelspacing=0.2) will reduce the spacing between entries to 2 points. The default on my install is about 0.5.
  • prop: which allows full control of the font size, etc. You can set an 8 point font using legend(..., prop={'size':8}). The default on my install is about 14 points.

In addition, the legend documentation lists a number of other padding and spacing parameters including: borderpad, handlelength, handletextpad, borderaxespad, and columnspacing. These all follow the same form as labelspacing and area also in multiples of fontsize.

These values can also be set as the defaults for all figures using the matplotlibrc file.


回答 5

在我的安装中,FontProperties仅更改文本大小,但它仍然太大且间隔开。我在pyplot.rcParams:中找到了一个参数legend.labelspacing,我猜它被设置为字体大小的一小部分。我已经改变了

pyplot.rcParams.update({'legend.labelspacing':0.25})

我不确定如何将其指定给pyplot.legend函数-传递

prop={'labelspacing':0.25}

要么

prop={'legend.labelspacing':0.25}

返回错误。

On my install, FontProperties only changes the text size, but it’s still too large and spaced out. I found a parameter in pyplot.rcParams: legend.labelspacing, which I’m guessing is set to a fraction of the font size. I’ve changed it with

pyplot.rcParams.update({'legend.labelspacing':0.25})

I’m not sure how to specify it to the pyplot.legend function – passing

prop={'labelspacing':0.25}

or

prop={'legend.labelspacing':0.25}

comes back with an error.


回答 6

plot.legend(loc =’右下角’,decimal_places = 2,fontsize =’11’,title =’嘿’,title_fontsize =’20’)

plot.legend(loc = ‘lower right’, decimal_places = 2, fontsize = ’11’, title = ‘Hey there’, title_fontsize = ’20’)