Size: 16192
Comment:
|
Size: 6394
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 10: | Line 10: |
= 命名(Naming) = | |
Line 11: | Line 12: |
= 命名(Naming) = | 应该选择一个容易记又有具体含义的名字。模块的命名可以随意一些(例如 twisted.spread ...),但是类命名必须十分清晰明了。写代码的时候请保证手边就有字典或是辞典,方便随时查看。 |
Line 13: | Line 15: |
应该避免用一个术语表示多种含义。要避免这个问题比想象中难的多,因为大多数常用的单词已经被许多其它软件用过了,所以这个规则经常被破坏。更重要的是,应该避免使用那些没有任何意义的单词。特别是像handler、processor、engine、manager和component这些词,这些词只能说明某个东西确实能做一些事情,但是并不能真的表述出这个东西的实际功能, |
|
Line 16: | Line 20: |
在命名和python的doc字串请使用美式拼写方法。例如,对于像filesystem这样的合成技术名词,在编码和doc字串中都应该使用没有连字符的拼写方式,以避免不必要的单词首字母大写问题。 |
|
Line 18: | Line 24: |
Testing | = 测试(Testing) = 单元测试应该使用twisted.trial框架编写。twisted.test包中有许多例子可以参考。测试模块的名称应该以“test_”开头。每个源码文件中都应该有一个“test-case-name”标签来指定与之相关的测试代码。 |
Line 20: | Line 29: |
验收测试(acceptance test)现在全部由admin/accepttests中的脚本自动完成。(TODO: 真正的验收测试策略) |
|
Line 23: | Line 34: |
在你checkin任何修改之前,请运行单元测试来测试你的代码。 |
|
Line 24: | Line 37: |
再次重申,在你checkin任何修改之前,请运行单元测试来测试你代码。由于验收测试通常是不可移植的,并且在某些情况下验收测试自身的运行也会出错,所以出现破坏功能约束的代码这种事儿也是不可避免的,我们也能理解,也可以原谅的。但如果不进行验收测试就提交代码,并造成了对原有功能的损害,就可能会导致从“大家对你的代码所造成的破坏的无情嘲弄”到“取消你在cvs上的commit权限”等各种后果。 |
|
Line 27: | Line 42: |
强烈建议开发者学会使用Emacs,并在Emacs中把TwistedEmacs包中的twisted-dev.el文件与F9绑定在一起用来运行单元测试。其它编辑器中现在还没有做类似的支持,但是如果您确实有需要,我们很乐意提供给你。 |
|
Line 28: | Line 45: |
如果你修改或是撰写了一个新的HOWTO文档,请参考Lore documentation来学习文档的编写格式。 |
|
Line 31: | Line 50: |
Whitespace | = 空白缩进(Whitespace) = 每个缩进的大小为4个空格键,不允许使用Tab键。强烈建议为每个代码段另起一行,这使代码中的控制结构的缩进更清晰。 |
Line 34: | Line 57: |
Modules | = 模块(Modules) = 模块的名称全部小写,并尽可短,最好是一个单词。如果模块的名称包含多个单词,可以使用下划线分隔或是直接将几个单词连起来写。 |
Line 36: | Line 62: |
大多数情况下,模块应该包含多个类,函数或是方法。如果一个模块只包含一个对象,可以考虑通过代码重构将一些相关的功能包含的该模块中。 |
|
Line 39: | Line 67: |
根据具体情况,下面的几种import方式都是可以的: |
|
Line 41: | Line 71: |
{{{ | |
Line 42: | Line 73: |
}}} 或是: |
|
Line 44: | Line 78: |
{{{ |
|
Line 45: | Line 81: |
}}} 也就是说,可以通过from ... import语句来导入module、class和function,但是不能通过from ... import语句导入一个package。 |
|
Line 47: | Line 86: |
Packages Package names should follow the same conventions as module names. All modules must be encapsulated in some package. Nested packages may be used to further organize related modules. __init__.py must never contain anything other than a docstring and (optionally) an __all__ attribute. Packages are not modules and should be treated differently. This rule may be broken to preserve backwards compatibility if a module is made into a nested package as part of a refactoring. If you wish to promote code from a module to a package, for example, to break a large module out into several smaller files, the accepted way to do this is to promote from within the module. For example, # parent/ # --- __init__.py --- import child # --- child.py --- import parent class Foo: pass parent.Foo = Foo Every package should be added to the list in setup.py. Packages must not depend circularly upon each other. To simplify maintaining this state, packages must also not import each other circularly. While this applies to all packages within Twisted, one twisted.python deserves particular attention, as it may not depend on any other Twisted package. Docstrings Wherever possible, docstrings should be used to describe the purpose of methods, functions, classes, and modules. In cases where it's desirable to avoid documenting thoroughly -- for example, and evolving interface -- insert a placeholder docstring ("UNDOCUMENTED" is preferred), so that the auto-generated API documentation will not pick up an extraneous comment as the documentation for that module/class/function. Docstrings are never to be used to provide semantic information about an object; this rule may be violated if the code in question is to be used in a system where this is a requirement (such as Zope). Docstrings should be indented to the level of the code they are documenting. Docstrings should be triple-quoted. Docstrings should be written in epytext format; more documentation is available in the Epytext Markup Language documentation. Additionally, to accommodate emacs users: Single quotes of the type of the docstring's triple-quote should be escaped. This will prevent font-lock from accidentally fontifying large portions of the file as a string. Code examples in docstrings should be prefixed by the | character. This will prevent IM-Python from regarding sample code as real functions, methods, and classes. For example, def foo2bar(f): """I am a function to convert foos to bars. I should be used when you have a foo but you want a bar; note that this is a non-destructive operation. If I can\'t convert the foo to a bar I will raise a FooException(). For example:: | import wombat | def sample(something): | f = something.getFoo() | f.doFooThing() | b = wombat.foo2bar(f) | b.doBarThing() | return b """ # Optionally, actual code can go here. Scripts For each script, that is, a program you expect a Twisted user to run from the command-line, the following things must be done: Write a module in twisted.scripts which contains a callable global named run. This will be called by the command line part with no arguments (it will usually read sys.argv). Feel free to write more functions or classes in this module, if you feel they are useful to others. Write a file in bin/ which contains the Twisted running-from-CVS header, and ending with from twisted.scripts.yourmodule import run run() Write a manpage in doc/man. On debian systems you can find a skeleton example of a manpage in /usr/share/doc/man-db/examples/manpage.example. Add your script to the script list in setup.py. This will insure your program will work correctly for users of CVS, Windows releases and Debian packages. Standard Library Extension Modules When using the extension version of a module for which there is also a Python version, place the import statement inside a try/except block, and import the Python version if the import fails. This allows code to work on platforms where the extension version is not available. For example: try: import cPickle as pickle except ImportError: import pickle Use the "as" syntax of the import statement as well, to set the name of the extension module to the name of the Python module. ChangeLog All changes that will affect the way end-users see Twisted should come with an appropriate entry in the ChangeLog that summarizes that impact. The correct format for the ChangeLog is GNU changelog format. There is an emacs mode for editing this, use M-x add-change-log-entry. If you are, for whatever absurd reason, using an editor other than emacs to edit Twisted, you can use Moshe Zadka's helpfully provided admin/change script to add a properly-formatted entry. Classes Classes are to be named in mixed case, with the first letter capitalized; each word separated by having its first letter capitalized. Acronyms should be capitalized in their entirety. Class names should not be prefixed with the name of the module they are in. Examples of classes meeting this criteria: twisted.spread.pb.ViewPoint twisted.parser.patterns.Pattern Examples of classes not meeting this criteria: event.EventHandler main.MainGadget An effort should be made to prevent class names from clashing with each other between modules, to reduce the need for qualification when importing. For example, a Service subclass for Forums might be named twisted.forum.service.ForumService, and a Service subclass for Words might be twisted.words.service.WordsService. Since neither of these modules are volatile (see above) the classes may be imported directly into the user's namespace and not cause confusion. Methods Methods should be in mixed case, with the first letter lower case, each word separated by having its first letter capitalized. For example, someMethodName, method. Sometimes, a class will dispatch to a specialized sort of method using its name; for example, twisted.reflect.Accessor. In those cases, the type of method should be a prefix in all lower-case with a trailing underscore, so method names will have an underscore in them. For example, get_someAttribute. Underscores in method names in twisted code are therefore expected to have some semantic associated with them. Some methods, in particular addCallback and its cousins return self to allow for chaining calls. In this case, wrap the chain in parenthesis, and start each chained call on a separate line, for example: return (foo() .addCallback(bar) .addCallback(thud) .addCallback(wozers)) Callback Arguments There are several methods whose purpose is to help the user set up callback functions, for example Deferred.addCallback or the reactor's callLater method. To make access to the callback as transparent as possible, most of these methods use **kwargs to capture arbitrary arguments that are destined for the user's callback. This allows the call to the setup function to look very much like the eventual call to the target callback function. In these methods, take care to not have other argument names that will steal the user's callback's arguments. When sensible, prefix these internal argument names with an underscore. For example, RemoteReference.callRemote is meant to be called like this: myref.callRemote("addUser", "bob", "555-1212") # on the remote end, the following method is invoked: def addUser(name, phone): ... where addUser is the remote method name. The user might also choose to call it with named parameters like this: myref.callRemote("addUser", name="bob", phone="555-1212") In this case, callRemote (and any code that uses the **kwargs syntax) must be careful to not use name, phone, or any other name that might overlap with a user-provided named parameter. Therefore, callRemote is implemented with the following signature: def callRemote(self, _name, *args, **kw): ... Do whatever you can to reduce user confusion. It may also be appropriate to assert that the kwargs dictionary does not contain parameters with names that will eventually cause problems. Special Methods The augmented assignment protocol, defined by __iadd__ and other similarly named methods, can be used to allow objects to be modified in place or to rebind names if an object is immutable -- both through use of the same operator. This can lead to confusing code, which in turn leads to buggy code. For this reason, methods of the augmented assignment protocol should not be used in Twisted. Functions Functions should be named similiarly to methods. Functions or methods which are responding to events to complete a callback or errback should be named _cbMethodName or _ebMethodName, in order to distinguish them from normal methods. Attributes Attributes should be named similarly to functions and methods. Attributes should be named descriptively; attribute names like mode, type, and buf are generally discouraged. Instead, use displayMode, playerType, or inputBuffer. Do not use Python's private attribute syntax; prefix non-public attributes with a single leading underscore. Since several classes have the same name in Twisted, and they are distinguished by which package they come from, Python's double-underscore name mangling will not work reliably in some cases. Also, name-mangled private variables are more difficult to address when unit testing or persisting a class. An attribute (or function, method or class) should be considered private when one or more of the following conditions are true: The attribute represents intermediate state which is not always kept up-to-date. Referring to the contents of the attribute or otherwise maintaining a reference to it may cause resources to leak. Assigning to the attribute will break internal assumptions. The attribute is part of a known-to-be-sub-optimal interface and will certainly be removed in a future release. Database Database tables will be named with plural nouns. Database columns will be named with underscores between words, all lower case, since most databases do not distinguish between case. Any attribute, method argument, or method name that corresponds directly to a column in the database will be named exactly the same as that column, regardless of other coding conventions surrounding that circumstance. All SQL keywords should be in upper case. C Code Wherever possible, C code should be optional, and the default python implementation should be maintained in tandem with it. C code should be strict ANSI C, and must build using GCC as well as Visual Studio for Windows, and really shouldn't have any problems with other compilers either. Don't do anything tricky. C code should only be used for efficiency, not for binding to external libraries. If your particular code is not frequently run, write it in Python. If you require the use of an external library, develop a separate, external bindings package and make your twisted code depend on it. Checkin Messages Thanks to CVSToys, the checkin messages are being used in a myriad of ways. Because of that, you need to observe a few simple rules when writing a checkin message. The first line of the message is being used as both the subject of the commit e-mail and the announcement on #twisted. Therefore, it should be short (aim for < 80 characters) and descriptive -- and must be able to stand alone (it is best if it is a complete sentence). The rest of the e-mail should be separated with hard line breaks into short lines (< 70 characters). This is free-format, so you can do whatever you like here. Checkin messages should be about what, not how: we can get how from CVS diff. Explain reasons for checkins, and what they affect. Each commit should be a single logical change, which is internally consistent. If you can't summarize your changes in one short line, this is probably a sign that they should be broken into multiple checkins. Recommendations These things aren't necessarily standardizeable (in that code can't be easily checked for compliance) but are a good idea to keep in mind while working on Twisted. If you're going to work on a fragment of the Twisted codebase, please consider finding a way that you would use such a fragment in daily life. I use the Twisted Web server on the main TML website, and aside from being good PR, this encourages you to actively maintain and improve your code, as the little everyday issues with using it become apparent. Twisted is a big codebase! If you're refactoring something, please make sure to recursively grep for the names of functions you're changing. You may be surprised to learn where something is called. Especially if you are moving or renaming a function, class, method, or module, make sure that it won't instantly break other code. Index Version: 1.3.0 |
在这里编辑"PyTwisted/WorkingOnTheTwistedCodeBase/CodingStandard".
Twisted编码标准 (Twisted Coding Standard)
命名(Naming)
应该选择一个容易记又有具体含义的名字。模块的命名可以随意一些(例如 twisted.spread ...),但是类命名必须十分清晰明了。写代码的时候请保证手边就有字典或是辞典,方便随时查看。
Try to choose names which are both easy to remember and meaningful. Some silliness is OK at the module naming level (see twisted.spread...) but when choosing class names, be as precise as possible. Write code with a dictionary and thesaurus open on the table next to you.
应该避免用一个术语表示多种含义。要避免这个问题比想象中难的多,因为大多数常用的单词已经被许多其它软件用过了,所以这个规则经常被破坏。更重要的是,应该避免使用那些没有任何意义的单词。特别是像handler、processor、engine、manager和component这些词,这些词只能说明某个东西确实能做一些事情,但是并不能真的表述出这个东西的实际功能,
Try to avoid overloaded terms. This rule is often broken, since it is incredibly difficult, as most normal words have already been taken by some other software. More importantly, try to avoid meaningless words. In particular, words like handler, processor, engine, manager and component don't really indicate what something does, only that it does something.
在命名和python的doc字串请使用美式拼写方法。例如,对于像filesystem这样的合成技术名词,在编码和doc字串中都应该使用没有连字符的拼写方式,以避免不必要的单词首字母大写问题。
Use American spelling in both names and docstrings. For compound technical terms such as 'filesystem', use a non-hyphenated spelling in both docstrings and code in order to avoid unnecessary capitalization.
测试(Testing)
单元测试应该使用twisted.trial框架编写。twisted.test包中有许多例子可以参考。测试模块的名称应该以“test_”开头。每个源码文件中都应该有一个“test-case-name”标签来指定与之相关的测试代码。
Unit tests are written using the twisted.trial framework. Many examples are in the twisted.test package. Test modules should start with 'test_' in their name. Source files should have test-case-name tags that point to their related tests.
验收测试(acceptance test)现在全部由admin/accepttests中的脚本自动完成。(TODO: 真正的验收测试策略)
Acceptance tests are all automated by the admin/accepttests script currently. (TODO: real acceptance tests strategy!)
在你checkin任何修改之前,请运行单元测试来测试你的代码。
Run the unit tests tests before you check anything in.
再次重申,在你checkin任何修改之前,请运行单元测试来测试你代码。由于验收测试通常是不可移植的,并且在某些情况下验收测试自身的运行也会出错,所以出现破坏功能约束的代码这种事儿也是不可避免的,我们也能理解,也可以原谅的。但如果不进行验收测试就提交代码,并造成了对原有功能的损害,就可能会导致从“大家对你的代码所造成的破坏的无情嘲弄”到“取消你在cvs上的commit权限”等各种后果。
Let me repeat that, for emphasis: run the unit tests before you check anything in. Code which breaks functionality is unfortunate and unavoidable. The acceptance tests are highly nonportable and sometimes a pain to run, so this is pardonable. Code which breaks the unit tests in a way that you could have prevented by running them yourself, however, may be grounds for anything from merciless taunting through revertion of the breakage to revocation of cvs commit privileges.
强烈建议开发者学会使用Emacs,并在Emacs中把TwistedEmacs包中的twisted-dev.el文件与F9绑定在一起用来运行单元测试。其它编辑器中现在还没有做类似的支持,但是如果您确实有需要,我们很乐意提供给你。
It is strongly suggested that developers learn to use Emacs, and use the twisted-dev.el file included in the TwistedEmacs package to bind the F9 key to run unit tests and bang on it frequently. Support for other editors is unavailable at this time but we would love to provide it.
如果你修改或是撰写了一个新的HOWTO文档,请参考Lore documentation来学习文档的编写格式。
If you modify, or write a new, HOWTO, please read the Lore documentation to learn the format the docs.
空白缩进(Whitespace)
每个缩进的大小为4个空格键,不允许使用Tab键。强烈建议为每个代码段另起一行,这使代码中的控制结构的缩进更清晰。
Indentation is 4 spaces per indent. Tabs are not allowed. It is preferred that every block appear on a new line, so that control structure indentation is always visible.
模块(Modules)
模块的名称全部小写,并尽可短,最好是一个单词。如果模块的名称包含多个单词,可以使用下划线分隔或是直接将几个单词连起来写。
Modules must be named in all lower-case, preferably short, single words. If a module name contains multiple words, they may be separated by underscores or not separated at all.
大多数情况下,模块应该包含多个类,函数或是方法。如果一个模块只包含一个对象,可以考虑通过代码重构将一些相关的功能包含的该模块中。
In most cases, modules should contain more than one class, function, or method; if a module contains only one object, consider refactoring to include more related functionality in that module.
根据具体情况,下面的几种import方式都是可以的:
Depending on the situation, it is acceptable to have imports that look like this:
from twisted.internet.defer import Deferred
或是:
or like this:
from twisted.internet import defer
也就是说,可以通过from ... import语句来导入module、class和function,但是不能通过from ... import语句导入一个package。
That is, modules should import modules or classes and functions, but not packages.