〔有些内容可能需要明确一下……〕
Data attributes override method attributes with the same name; to avoid accidental name conflicts, which may cause hard-to-find bugs in large programs, it is wise to use some kind of convention that minimizes the chance of conflicts. Possible conventions include capitalizing method names, prefixing data attribute names with a small unique string (perhaps just an underscore), or using verbs for methods and nouns for data attributes.
同名的数据属性会覆盖方法属性,为了避免可能的命名冲突--这在大型程序中可能会导致难以发现的 bug --最好以某种命名约定来避免冲突。可选的约定包括方法的首字母大写,数据属性名前缀小写(可能只是一个下划线),或者方法使用动词而数据属性使用名词。
Data attributes may be referenced by methods as well as by ordinary users (``clients'') of an object. In other words, classes are not usable to implement pure abstract data types. In fact, nothing in Python makes it possible to enforce data hiding -- it is all based upon convention. (On the other hand, the Python implementation, written in C, can completely hide implementation details and control access to an object if necessary; this can be used by extensions to Python written in C.)
数据属性可以由方法引用,也可以由普通用户(客户)调用。换句话说,类不能实现纯的数据类型。事实上 Python 中没有什么办法可以强制隐藏数据--一切都基本约定的惯例。(另一方法讲,Python 的实现是用 C 写成的,如果有必要,可以用 C 来编写 Python 扩展,完全隐藏实现的细节,控制对象的访问。)
Clients should use data attributes with care -- clients may mess up invariants maintained by the methods by stamping on their data attributes. Note that clients may add data attributes of their own to an instance object without affecting the validity of the methods, as long as name conflicts are avoided -- again, a naming convention can save a lot of headaches here.
客户应该小心使用数据属性--客户可能会因为随意修改数据属性而破坏了本来由方法维护的数据一致性。需要注意的是,客户只要注意避免命名冲突,就可以随意向实例中添加数据属性而不会影响方法的有效性--再次强调,命名约定可以省去很多麻烦。
There is no shorthand for referencing data attributes (or other methods!) from within methods. I find that this actually increases the readability of methods: there is no chance of confusing local variables and instance variables when glancing through a method.
从方法内部引用数据属性(以及其它方法!)没有什么快捷的方式。我认为这事实上增加了方法的可读性:即使粗略的浏览一个方法,也不会有混淆局部变量和实例变量的机会。
Conventionally, the first argument of methods is often called
self
. This is nothing more than a convention: the name
self
has absolutely no special meaning to Python. (Note,
however, that by not following the convention your code may be less
readable by other Python programmers, and it is also conceivable that
a class browser program be written which relies upon such a
convention.)
习惯上,方法的第一个参数命名为 self
。这仅仅是一个约定:对
Python 而言,self
绝对没有任何特殊含义。(然而要注意的是,如果不遵守这个约定,别的
Python
程序员阅读你的代码时会有不便,而且有些类浏览程序也是遵循此约定开发的。)
Any function object that is a class attribute defines a method for instances of that class. It is not necessary that the function definition is textually enclosed in the class definition: assigning a function object to a local variable in the class is also ok. For example:
类属性中的任何函数对象在类实例中都定义为方法。不是必须要将函数定义代码写进类定义中,也可以将一个函数对象赋给类中的一个变量。例如:
# Function defined outside the class def f1(self, x, y): return min(x, x+y) class C: f = f1 def g(self): return 'hello world' h = g
Now f
, g
and h
are all attributes of class
C that refer to function objects, and consequently they are all
methods of instances of C -- h
being exactly equivalent
to g
. Note that this practice usually only serves to confuse
the reader of a program.
现在 f
, g
和 h
都是类 C
的属性,引用的都是函数对象,因此它们都是 C 实例的方法--
h
严格等于 g
。要注意的是这种习惯通常只会迷惑程序的读者。
Methods may call other methods by using method attributes of the
self
argument:
通过 self
参数的方法属性,方法可以调用其它的方法:
class Bag: def __init__(self): self.data = [] def add(self, x): self.data.append(x) def addtwice(self, x): self.add(x) self.add(x)
Methods may reference global names in the same way as ordinary functions. The global scope associated with a method is the module containing the class definition. (The class itself is never used as a global scope!) While one rarely encounters a good reason for using global data in a method, there are many legitimate uses of the global scope: for one thing, functions and modules imported into the global scope can be used by methods, as well as functions and classes defined in it. Usually, the class containing the method is itself defined in this global scope, and in the next section we'll find some good reasons why a method would want to reference its own class!
方法可以像引用普通的函数那样引用全局命名。与方法关联的全局作用域是包含类定义的模块。(类本身永远不会做为全局作用域使用!)尽管很少有好的理由在方法中使用全局数据,全局作用域确有很多合法的用途:其一是方法可以调用导入全局作用域的函数和方法,也可以调用定义在其中的类和函数。通常,包含此方法的类也会定义在这个全局作用域,在下一节我们会了解为何一个方法要引用自己的类!