笔记-python tutorial-9.classes

1.      Classes

1.1.    scopes and namespaces

namespace: A namespace is a mapping from names to objects.

典型的命名空间有:built-in names;the global names in a module; the local names in a function.

两个命名空间中的名称之间没有任何关系,例如两个模块可以都定义一个函数func1(),但在使用时需要加上模块名做前缀以示区别。

属性是只读或可写的。

namespaces are created at different moments and have different lifetimes. The namespace containing the built-in names is created when the Python interpreter starts up, and is never deleted.

The global namespace for a module is created when the module definition is read in; normally, module namespaces also last until the interpreter quits.

The statements executed by the top-level invocation of the interpreter, either read from a script file or interactively, are considered part of a module called __main__, so they have their own global namespace. (The built-in names actually also live in a module; this is called builtins.)

The local namespace for a function is created when the function is called, and deleted when the function returns or raises an exception that is not handled within the function. (Actually, forgetting would be a better way to describe what actually happens.) Of course, recursive invocations each have their own local namespace.

scope:A scope is a textual region of a Python program where a namespace is directly accessible. “Directly accessible” here means that an unqualified reference to a name attempts to find the name in the namespace.

Although scopes are determined statically, they are used dynamically. At any time during execution, there are at least three nested scopes whose namespaces are directly accessible:

  • the innermost scope, which is searched first, contains the local names
  • the scopes of any enclosing functions, which are searched starting with the nearest enclosing scope, contains non-local, but also non-global names
  • the next-to-last scope contains the current module’s global names
  • the outermost scope (searched last) is the namespace containing built-in names

如果名字声明为全局,则所有声明为global的名称均为同一个,有点绕,效果见下面的测试。

# 奇怪的测试

def fun1():

num = 5

def fun2():

global num

num = 6

print('fun2',num)

def fun3():

num = 7

print('fun3',num)

def fun4():

global num

print('fun4',num)

fun4()

fun3()

fun2()

fun1()

输出:

fun2 6

fun3 7

fun4 6

A special quirk of Python is that – if no global statement is in effect – assignments to names always go into the innermost scope. Assignments do not copy data — they just bind names to objects. The same is true for deletions: the statement del x removes the binding of x from the namespace referenced by the local scope. In fact, all operations that introduce new names use the local scope: in particular, importstatements and function definitions bind the module or function name in the local scope.

这段不是很明白具体的意思。不过下面的代码会报错。

# 奇怪的测试

# 奇怪的测试

def fun1():

num = 5

def fun2():

#global num

num = 6

print('fun2',num)

def fun3():

num = 7

print('fun3',num)

def fun4():

global num

#num = 9

print('fun4',num)

fun4()

fun3()

fun2()

fun1()

print(num)

报错显示在fun4()中name ‘num’ is not defined,但去掉任何一个或两个#号都可以正常运行。

1.1.1.   scopes and namespaces example

下面是一段效果演示代码:

def scope_test():

def do_local():

spam = "local spam"

def do_nonlocal():

nonlocal spam

spam = "nonlocal spam"

def do_global():

global spam

spam = "global spam"

spam = "test spam"

do_local()

print("After local assignment:", spam)

do_nonlocal()

print("After nonlocal assignment:", spam)

do_global()

print("After global assignment:", spam)

scope_test()

print("In global scope:", spam)

输出:

After local assignment: test spam

After nonlocal assignment: nonlocal spam

After global assignment: nonlocal spam

In global scope: global spam

1.2.    类基础介绍

1.2.1.   class definition syntax

class ClassName():

<statement-1>

……

1.2.2.   class objects

class objects support two kinds of operations:attribute reference and instantiation.

1.2.3.   instance objects

there are two kinds of valid atribute names, data attributes and methods.

data attributes correspond to “instance variables” in Smalltalk, and to “data members” in C++. Data attributes need not be declared; like local variables, they spring into existence when they are first assigned to.

A method is a function that “belongs to” an object.

method可以通过以下方式引用:

x.f()

实例方法调用时实例对象作为函数的第一个参数传递。

1.2.4.   class and instance variables

class Dog:

kind = 'canine'         # class variable shared by all instances

def __init__(self, name):

self.name = name    # instance variable unique to each instance

>>> d = Dog('Fido')

>>> e = Dog('Buddy')

>>> d.kind                  # shared by all dogs

'canine'

>>> e.kind                  # shared by all dogs

'canine'

>>> d.name                  # unique to d

'Fido'

>>> e.name                  # unique to e

'Buddy'

一般而言,实例变量用于保存实例数据,而类变量可以被整个类的实例共享。

一般情况下类变量不使用可变类型。

1.3.    类的继承

派生类定义:

class DerivedClassName(BaseClassName):

<statement-1>

.

.

.

<statement-N>

基类名必需是对定义语句可访问的,对于不同模块中的类继承可以使用以下方式;

class DerivedClassName(modname.BaseClassName):

构造类对象时,会记住基类。如果在类中找不到属性,则向上递归在基类中寻找。

Python中有两个内置函数用于查看继承类:

isinstance(obj, int):检查是否某一类

issubclass(bool, int):检查是否为某类的子类

1.3.1.   多继承

python支持多继承

class DerivedClassName(Base1, Base2, Base3):

<statement-1>

.

.

.

<statement-N>

大多数情况下,在父类中查找属性的顺序是深度优先,从左至右,如果在层次结构中有重叠也不会搜索两次。

python支持super(),这一机制在其它语言中叫做call-next-method。

因为多继承都会表现出一个或多个菱形拓扑关系图,为防止基类被多次访问,动态算法保证只调用每个父类一次。

1.4.    private variables私有变量

python中并不存在真正的“私有”变量,但是,多数代码都遵守一个约定,以_为前缀的名称是api的非公共部分(包括函数,方法或数据成员)。

class Mapping:

def __init__(self, iterable):

self.items_list = []

self.__update(iterable)

def update(self, iterable):

for item in iterable:

self.items_list.append(item)

__update = update   # private copy of original update() method

class MappingSubclass(Mapping):

def update(self, keys, values):

# provides new signature for update()

# but does not break __init__()

for item in zip(keys, values):

self.items_list.append(item)

1.5.    iterators迭代实现

for语句实际上使用了迭代来实现,__next__()一次抛出一个元素,没有更多元素时,__next__()抛出一个StopIteration异常告诉for终止循环。

也可以使用内建函数next()自己调用__next__()方法

>>> s = 'abc'

>>> it = iter(s)

>>> it

<iterator object at 0x00A1DB50>

>>> next(it)

'a'

>>> next(it)

'b'

>>> next(it)

'c'

>>> next(it)

Traceback (most recent call last):

File "<stdin>", line 1, in <module>

next(it)

StopIteration

下面是一个自定义附有迭代功能的类定义代码:

class Reverse:

"""Iterator for looping over a sequence backwards."""

def __init__(self, data):

self.data = data

self.index = len(data)

def __iter__(self):

return self

def __next__(self):

if self.index == 0:

raise StopIteration

self.index = self.index - 1

return self.data[self.index]

>>> rev = Reverse('spam')

>>> iter(rev)

<__main__.Reverse object at 0x00A1DB50>

>>> for char in rev:

...     print(char)

...

m

a

p

s

1.6.    generators

生成器是创建迭代器的工具,写起来很像正常的语句,但当要返回值时使用yield语句。每一次next()调用它时,生成器记住它离开的位置(包括数据和最后一个语句)。

下面是一个生成器示例:

def reverse(data):

for index in range(len(data)-1, -1, -1):

yield data[index]

>>> for char in reverse('golf'):

...     print(char)

...

f

l

o

g

当生成器终止时,自动抛出StopIteration异常。

1.7.    generator expressions

一些简单的生成器可以使用类似于列表推导式的语法,但需要使用括号而不是方括号。这些表达式一般用于立即生成数据,生成器表达式比完整的的生成器定义更简洁但功能更少,而且往往比等效的列表推导占用更少内存。

示例:

>>> sum(i*i for i in range(10))                 # sum of squares

285

>>> xvec = [10, 20, 30]

>>> yvec = [7, 5, 3]

>>> sum(x*y for x,y in zip(xvec, yvec))         # dot product

260

>>> from math import pi, sin

>>> sine_table = {x: sin(x*pi/180) for x in range(0, 91)}

>>> unique_words = set(word  for line in page  for word in line.split())

>>> valedictorian = max((student.gpa, student.name) for student in graduates)

>>> data = 'golf'

>>> list(data[i] for i in range(len(data)-1, -1, -1))

['f', 'l', 'o', 'g']

笔记-python tutorial-9.classes的更多相关文章

  1. [译]The Python Tutorial#9. Classes

    写在前面 本篇文章是<The Python Tutorial>(3.6.1),第九章,类的译文. 9. Classes 与其他编程语言相比,Python的类机制定义类时,最小化了新的语法和 ...

  2. Python Tutorial笔记

    Python Tutorial笔记 Python入门指南 中文版及官方英文链接: Python入门指南 (3.5.2) http://www.pythondoc.com/pythontutorial3 ...

  3. 笔记-python lib-pymongo

    笔记-python lib-pymongo 1.      开始 pymongo是python版的连接库,最新版为3.7.2. 文档地址:https://pypi.org/project/pymong ...

  4. [译]The Python Tutorial#8. Errors and Exceptions

    [译]The Python Tutorial#Errors and Exceptions 到现在为止都没有过多介绍错误信息,但是已经在一些示例中使用过错误信息.Python至少有两种类型的错误:语法错 ...

  5. [译]The Python Tutorial#4. More Control Flow Tools

    [译]The Python Tutorial#More Control Flow Tools 除了刚才介绍的while语句之外,Python也从其他语言借鉴了其他流程控制语句,并做了相应改变. 4.1 ...

  6. [Notes] Learn Python2.7 From Python Tutorial

    I have planed to learn Python for many times. I have started to learn Python for many times . Howeve ...

  7. Python Tutorial 学习(八)--Errors and Exceptions

    Python Tutorial 学习(八)--Errors and Exceptions恢复 Errors and Exceptions 错误与异常 此前,我们还没有开始着眼于错误信息.不过如果你是一 ...

  8. Python Tutorial 学习(六)--Modules

    6. Modules 当你退出Python的shell模式然后又重新进入的时候,之前定义的变量,函数等都会没有了. 因此, 推荐的做法是将这些东西写入文件,并在适当的时候调用获取他们. 这就是为人所知 ...

  9. 笔记-python操作mysql

    笔记-python操作mysql 1.      开始 1.1.    环境准备-mysql create database db_python; use db_python; create tabl ...

随机推荐

  1. .net 中的托管与非托管

    托管代码 托管代码就是Visual Basic .NET和C#编译器编译出来的代码.编译器把代码编译成中间语言(IL),而不是能直接在你的电脑上运行的机器码.中间语言被封装在一个叫程序集(assemb ...

  2. EL_JSTL

    EL(Expression Language)EL表达式 作用:在JSP中消灭java代码 语法: "${ }" 用法:参考jsp页面 //Servlet中,: User user ...

  3. 构建高性能JavaScript应用

    前端性能优化准则: 一.减少http请求.     措施:合并小图片,css控制背景图.合并CSS,合并JS 二.使用CDN(Content Deliver Network 内容分发网络)发布静态资源 ...

  4. linux下安装redis和部署

    转自简书:https://www.jianshu.com/p/bc84b2b71c1c 1.基础知识  redis是用C语言开发的一个开源的高性能键值对(key-value)数据库.它通过提供多种键值 ...

  5. node模拟后台返回json书写格式报错--Unexpected token ' in JSON at position 1

    最近在学习Node的知识,就尝试写了一个注册登陆的简单功能,但是自己在模拟后台返回值的时候,总是报错Unexpected token ' in JSON at position 1,查找原因之后,是因 ...

  6. Lua学习---函数定义

    1.函数定义的格式: Lua使用function定义函数,语法如下: function function_name (arc) --arc表示参数列表,函数的参数列表可以为空 --body end 上 ...

  7. koa2实现文件上传服务

    使用方法 方法一: 使用中间介 koa-body 方法二: 自己写个借口去接收数据流并保存 方法三: 使用 koa-body 接受文件,自己写个接口做文件保存或处理等操作 这里简单记录方法三 app. ...

  8. cms-登陆

    先介绍下登陆的思路: 1.在登陆页面首先前端验证用户名和密码是否正确,如果验证通过,则ajax的方式向后台提交数据. 2.在controller层,将得到的用户名名和密码封装进shiro的token, ...

  9. c++ STL stack容器成员函数

    这是后进先出的栈,成员函数比较简单,因为只能操作栈顶的元素.不提供清除什么的函数. 函数 描述 bool s.empty() 栈是否为空(即size=0).若空,返回true,否则,false. vo ...

  10. EF和linq语句查询条件不等于某个参数出现的问题

    where t.a!=字符串   这是错误的写法,正确为 where t.a!=字符串.trim() 其他类型变量需要保持实体类型和查询条件参数的类型是一致的,不然出现的语句可能会是 类似`Exten ...