Introduction to Python/zh-cn

本简短教程可供Python新手参阅. Python是一种开源、支持多平台的 编程语言. Python有几种不同于其他常见语言的特性，使之与众不同，而且还易于对此毫无经验的人使用：


 * Python被设计为一种易于常人阅读的语言，因此方便学习且代码容易理解.
 * Python是一种解释型语言，也就是它并非C那样的编译型语言，在程序运行前无需进行编译. 您所编写的代码将如您所愿即刻逐行执行. 由于代码可放慢脚步逐行执行，因此更便于学习与查找代码中错误.
 * 可将Python嵌入其他程序用作脚本语言. FreeCAD中配有一个内嵌的Python解释器；您可以在FreeCAD中编写Python代码来控制FreeCAD的各种组件，比如用来创建一个几何图形等等. 这是一种极其强大的工具，程序员可通过它编写代码，以此取代仅能点击标有"创建球体"按钮的机械式操作；您可以借此自由方便地构建自己的工具，创建精准的几何图形，但程序员可能无法预览待创建的图形.
 * Python具有可扩展性，您可以轻松地为它接入新的模块来拓展其功能. 例如，您可以借助特定模块使Python可以读写jpg图片、与twitter进行交互，甚至调度任务在操作系统上的执行，等等.

我们墙裂鼓励您亲自将代码输入至Python解释器. 经过我们的激烈讨论，认为重点在于令代码跑起来，并显示出结果. 不运行代码根本不会理解Python. 因此，快动手吧！以下是相关简介，而并非完整的教程. 但是我们希望这能为您深入理解FreeCAD中的内部机制而提供相关的基础知识.

解释器
用户在写程序时通常会打开文本编辑器或特定的编程环境(一般是配有其他辅助工具的文本编辑器)，借此编写代码、编译并执行. 当代码中存在一个或多个错误时，程序往往就跑不起来了. 这时，您可以根据报错信息定位错误的根源. 再返回编辑器，纠正错误，再次运行，如此往复直到程序可按预期执行为止.

在整个处理流程中，Python解释器的内部工作原理对用户而言都是透明的. 所谓的解释器是一种附有命令提示符的Python窗口，在此，您可以方便地输入Python代码. 如果您在自己的计算机上安装了Python(如果系统为Windows或Mac，从Python website下载；如果系统是GNU/Linux，则借助软件包资料库（package repository）进行安装), 您可从开始菜单中开启Python解释器. 但是，FreeCAD中的下方窗口中也集成了Python解释器：



(如果没有找到，请依次点选View --> Panels --> Python console. )

解释器中显示着Python的版本，a >>>即为命令提示符，您可以在此输入Python代码. 在解释器中编写代码很简单：一行对应一个指令. 在按下回车键时，将执行本行代码(此前将自动在背后进行代码编译). 例如，请尝试编写下列代码：

是一种特殊的Python关键字，顾名思义，它负责在屏幕上打印内容. 当您按下回车键时，将处理所输入的代码，最后打印"hello"这条消息. 如果您得到了一个错误信息，例如，让我们来这样写：

Python将告知我们，它不知道hello是神马. 利用"符号可方便地指定字符串内的多个字符，用编程术语来讲，即一段文本. 若不使用"符号，则print命令将认为hello并非一段文本，而是一个特殊的Python关键字. 而重点在于，您会立即得到一个因此而产生的错误消息. 通过按“up”键(或者在FreeCAD解释器中按CTRL+up)，您将返回上一条编写的命令，并对此进行修正.

Python解释器中还设有一个内建的帮助系统. 尝试输入：

或者，例如，当我们不知道上述打印hello命令哪里出了问题，而希望得知与"print"命令有关的信息时：

您将得到一条既长又完整的print命令功能的描述.

现在让我们来全面了解一下Python解释器，先从最关键的部分入手吧！

变量
实话实说，打印"hello"字符串没什么意思. 更有趣的是打印我们没有提前得知的内容，或令Python来为我们求出所需的内容. 这便是引入变量这一概念的原因. 简而言之，变量即为：存有特定值的名称. 例如，输入下列内容：

我猜您已经知道这段代码的背后究竟发生了什么，我们将"hello"存在了"a"名下. 现在，"a"在Python环境中已经不再是一个未知的名称了！我们可以在各处运用它，例如，将其用于上述打印命令中. 我们几乎可以使用能想到的任意名称，仅需遵循一些简单的规则即可，比如名称中不能夹带空格与特定的标点符号. 例如，我们可以这样写：

看到了吗？现在的hello是一个有定义的单词. 但是，当我们无意中选取了Python中已经存在的名称作为变量名时会发生什么呢？这里，我们选取"print"作为变量名来保存字符串：

Python很机智，告诉我们：没戏. 它自己有一些"保留"的关键字是用户不能修改的. 但是我们自己的变量却可以任意修改，这就是它们为什么被称为变量：内容可变. 例如：

我们可以改变myVariable的值. 也可以复制变量：

请注意，关键的是要给变量起个有意义的名称. 这是因为，经过一段时间后您可以会忘记变量"a"表示的是什么. 例如，将某个变量命名myWelcomeMessage后，您可以轻松回忆起设立此变量的目的. 这样便可以使您的代码直观地表达出自身的意义.

字母的大小写也非常重要. myVariable与myvariable是两个截然不同的变量，区别就在于其中字母v的大小写上. 如果您输入print myvariable，系统就会返回一个“未定义”错误.

Numbers
Of course you must know that programming is useful to treat all kinds of data, and especially numbers, not only text strings. One thing is important, Python must know what kind of data it is dealing with. We saw in our print hello example, that the print command recognized our "hello" string. That is because by using the ", we told specifically the print command what follows next is a text string.

We can always check the data type of a variable with the special Python keyword type:

It will tell us the contents of myVar is 'str', short for string in Python jargon. We have also other basic types of data, such as integer and float numbers:

This is much more interesting, isn't it? Now we have a powerful calculator! Look at how well it worked, Python knows that 10 and 20 are integer numbers. So they are stored as "int", and Python can do with them everything it can do with integers. Look at the results of this:

See? We forced Python to consider that our two variables are not numbers but mere pieces of text. Python can add two pieces of text together, but it won't try to find out any sum. But we were talking about integer numbers. There are also float numbers. The difference is that integer numbers don't have decimal part, while float numbers can have a decimal part:

Int and Floats can be mixed together without problem:

Of course the total has decimals, right? Then Python automatically decided that the result is a float. In several cases such as this one, Python automatically decides what type to use. In other cases it doesn't. For example:

This will give us an error, varA is a string and varB is an int, and Python doesn't know what to do. However, we can force Python to convert between types:

Now both are strings, the operation works! Note that we "stringified" varB at the time of printing, but we didn't change varB itself. If we wanted to turn varB permanently into a string, we would need to do this:

We can also use int and float to convert to int and float if we want:

Note on Python commands

You must have noticed that in this section we used the print command in several ways. We printed variables, sums, several things separated by commas, and even the result of other Python command such as type. Maybe you also saw that doing those two commands,

have exactly the same result. That is because we are in the interpreter, and everything is automatically printed. When we write more complex programs that run outside the interpreter, they won't print automatically, so we'll need to use the print command. From now on, let's stop using it here, it'll go faster. So we can simply write:

You must have seen that most of the Python commands (or keywords) type, int, str, etc. have parenthesis to limit the command contents. The only exception is the print command, which in fact is not really an exception, as it also works normally: print("hello"). However, since it is used often, the Python designers allowed a simpler version.

Lists
Another interesting data type is a list. A list is simply a collection of other data. The same way that we define a text string by using " ", we define a list by using [ ]:

You see that it can contain any type of data. Lists are very useful because you can group variables together. You can then do all kinds of things within that group, for example counting them:

or retrieving one item of a list:

You see that while the len command returns the total number of items in a list, their "position" in the list begins with 0. The first item in a list is always at position 0, so in our myOtherList, "Bob" will be at position 2. We can do much more with lists, you can read here, such as sorting contents, removing or adding elements.

A funny and interesting thing: a text string is very similar to a list of characters! Try doing this:

Usually, what you can do with lists can also be done with strings. In fact both lists and strings are sequences.

Outside strings, ints, floats and lists, there are more built-in data types, such as dictionaries, or you can even create your own data types with classes.

Indentation
One big cool use of lists is also browsing through them and do something with each item. For example look at this:

We iterated (programming jargon) through our list with the "for ... in ..." command and did something with each of the items. Note the special syntax: the for command terminates with : indicating the following will be a block of one of more commands. In the interpreter, immediately after you enter the command line ending with :, the command prompt will change to ... which means Python knows that a colon ended line has happened and more is coming.

How will Python know how many of the next lines will be to be executed inside the for...in operation? For that, Python uses indentation. That is, your next lines won't begin immediately. You will begin them with a blank space, or several blank spaces, or a tab, or several tabs. Other programming languages use other methods, like putting everything inside parenthesis, etc. As long as you write your next lines with the same indentation, they will be considered part of the for-in block. If you begin one line with 2 spaces and the next one with 4, there will be an error. When you finished, just write another line without indentation, or simply press Enter to come back from the for-in block

Indentation is cool because it aids in program readability. If you use large indentations (for example use tabs instead of spaces because it's larger), when you write a big program you'll have a clear view of what is executed inside what. We'll see that commands other than for-in, can have indented blocks of code too.

For-in commands can be used for many things that must be done more than once. It can, for example, be combined with the range command:

(If you have been running the code examples in an interpreter by Copying and Pasting, you will find the previous block of text will throw an error. Instead, copy to the end of the indented block, i.e. the end of the line total = total + number and then paste to the interpreter.  In the interpreter issue an until the three dot prompt disappears and the code runs.  Then copy the final two lines into the interpreter followed by one or more The final answer should appear.)

If you would type into the interpreter help(range) you would see:

Here the square brackets denote an optional parameter. However all are expected to be integers. Below we will force the range parameters to be an integer using int

Or more complex things like this:

You see that the range command also has that strange particularity that it begins with 0 (if you don't specify the starting number) and that its last number will be one less than the ending number you specify. That is, of course, so it works well with other Python commands. For example:

Another interesting use of indented blocks is with the if command. If executes a code block only if a certain condition is met, for example:

Of course this will always print the first sentence, but try replacing the second line by:

Then nothing is printed. We can also specify an else: statement:

Functions
There are few standard Python commands. In the current version of Python, there are about 30, and we already know several of them. But imagine if we could invent our own commands? Well, we can, and it's extremely easy. In fact, most the additional modules that you can plug into your Python installation do just that, they add commands that you can use. A custom command in Python is called a function and is made like this:

(Another copy and paste error, only copy through the end of the indented section i.e. " square meters" Paste to the interpreter, and issue until the three dot prompt goes a way, then copy and paste the final line.)

Extremely simple: the def command defines a new function. You give it a name, and inside the parenthesis you define arguments that we'll use in our function. Arguments are data that will be passed to the function. For example, look at the len command. If you just write len alone, Python will tell you it needs an argument. That is, you want len of something, right? Then, for example, you'll write len(myList) and you'll get the length of myList. Well, myList is an argument that you pass to the len function. The len function is defined in such a way that it knows what to do with what is passed to it. Same as we did here.

The "myValue" name can be anything, and it will be used only inside the function. It is just a name you give to the argument so you can do something with it, but it also serves to tell the function how many arguments to expect. For example, if you do this:

There will be an error. Our function was programmed to receive just one argument, but it received two, 45 and 34. We could instead do something like this:

We made a function that receives two arguments, sums them, and returns that value. Returning something is very useful, because we can do something with the result, such as store it in the myTotal variable. Of course, since we are in the interpreter and everything is printed, doing:

will print the result on the screen, but outside the interpreter, since there is no print command inside the function, nothing would appear on the screen. You would need to:

to have something printed. Read more about functions here.

Modules
Now that we have a good idea of how Python works, we'll need one last thing: How to work with files and modules.

Until now, we wrote Python instructions line by line in the interpreter, right? What if we could write several lines together, and have them executed all at once? It would certainly be handier for doing more complex things. And we could save our work too. Well, that too, is extremely easy. Simply open a text editor (such as the windows notepad, Linux gedit, emacs, or vi), and write all your Python lines, the same way as you write them in the interpreter, with indentations, etc. Then, save that file somewhere, preferably with a .py extension. That's it, you have a complete Python program. Of course, there are much better editors than notepad, but it is just to show you that a Python program is nothing else than a text file.

To make Python execute that program, there are hundreds of ways. In windows, simply right-click your file, open it with Python, and execute it. But you can also execute it from the Python interpreter itself. For this, the interpreter must know where your .py program is. In FreeCAD, the easiest way is to place your program in a place that FreeCAD's Python interpreter knows by default, such as FreeCAD's bin folder, or any of the Mod folders. (In Linux, you probably have a directory /home/ /.FreeCAD/Mod, let's add a subdirectory to that called scripts where we will put the text file.) Suppose we write a file like this:

and we save it as myTest.py in our FreeCAD/bin directory (or on Linux to /home/ /.FreeCAD/Mod/scripts.) Now, let's start FreeCAD, and in the interpreter window, write:

without the .py extension. This will simply execute the contents of the file, line by line, just as if we had written it in the interpreter. The sum function will be created, and the message will be printed. There is one big difference: the import command is made not only to execute programs written in files, like ours, but also to load the functions inside, so they become available in the interpreter. Files containing functions, like ours, are called modules.

Normally when we write a sum function in the interpreter, we execute it simply like that:

Like we did earlier. When we import a module containing our sum function, the syntax is a bit different. We do:

That is, the module is imported as a "container", and all its functions are inside. This is extremely useful, because we can import a lot of modules, and keep everything well organized. So, basically, everywhere you see something.somethingElse, with a dot in between, that means somethingElse is inside something.

We can also import our sum function directly into the main interpreter space, like this:

Basically all modules behave like that. You import a module, then you can use its functions: module.function(argument). Almost all modules do that: they define functions, new data types and classes that you can use in the interpreter or in your own Python modules, because nothing prevents you from importing other modules inside your module!

One last extremely useful thing. How do we know what modules we have, what functions are inside and how to use them (that is, what kind of arguments they need)? We saw already that Python has a help function. Doing:

Will give us a list of all available modules. We can now type q to get out of the interactive help, and import any of them. We can even browse their content with the dir command

We'll see all the functions contained in the math module, as well as strange stuff named __doc__, __file__, __name__. The __doc__ is extremely useful, it is a documentation text. Every function of (well-made) modules has a __doc__ that explains how to use it. For example, we see that there is a sin function in side the math module. Want to know how to use it?

(It may not be evident, but on either side of doc are two underscore characters.)

And finally one last little goodie: When we work on a new or existing module, it's best to replace the file extension with py such as: myModule.FCMacro => myModule.py. We often want to test it so we will load it as above.

But what if we see that myTestFunction doesn't work correctly? We go back to our editor and make changes. Then, instead of closing and reopening the python interpreter, we can simply update the module like this:

This file renaming is because Python doesn't know about the extension FCMacro.

However, there are two alternates: Inside the one macro use Python's exec or execfile functions.

or

For Python 3.xxx replace this code with:

To share code across macros, you can access the FreeCAD or FreeCADGui module (or any other Python module) and set any attribute to it. This should survive the execution of the macro.

Starting with FreeCAD
Well, I think you now have a good idea of how Python works, and you can start exploring what FreeCAD has to offer. FreeCAD's Python functions are all well organized in different modules. Some of them are already loaded (imported) when you start FreeCAD. So, just do

and read on to FreeCAD Scripting Basics.

Of course, we saw here only a very small part of the Python world. There are many important concepts that we didn't mention. There are three very important Python reference documents on the net: Be sure to bookmark them!
 * the official Python tutorial with way more information than this one
 * the official Python reference
 * the Dive into Python wikibook/ book.