《Python进阶》笔记

忘记从哪得知《Python进阶》这本书了,前几天花了几个小时读完之后,学到了很多以前不知道或是不了解的关于Python的种种,先挑几条比较实用的记录一下,以后再详细探讨。

1. open函数

很多人(也包括我)经常是这样使用open函数的:

f = open('data.txt', 'r')
data = f.read()
f.close()

但是,这种使用方式有一个隐患:open的返回值是操作系统分配的一个文件句柄,处理完文件需要归还这个文件句柄,避免超出一次能打开的文件句柄数上限。在如上代码中,如果有任意异常正好在f = open(…)之后产生,f.close()将不会被调用(文件句柄被归还与否,取决于Python解释器的实现),为了确保无论是否产生异常文件都能被关闭,可以使用Python中的with语句:

with open('data.txt', 'r') as f:
data = f.read()

C++引用计数的简单实现

C++标准库中的 shared_ptr 是引用计数型指针,记录有多少用户共享它所指向的对象。当没有用户使用对象时,shared_ptr 类负责释放资源。为了说明引用计数如何工作,我将结合《C++ Primer(第5版)》第 13 章的内容,设计自己的引用计数。

引用计数的工作方式

  1. 除了初始化对象外,每个构造函数(拷贝构造函数除外)还要创建一个引用计数,用来记录有多少对象与正在创建的对象共享状态。当我们创建一个对象时,只有一个对象共享状态,因此将计数器初始化为 1。
  2. 拷贝构造函数不分配新的计数器,而是拷贝给定对象的数据成员,包括计数器。拷贝构造函数递增共享的计数器,指出给定对象的状态又被一个新用户所共享。
  3. 析构函数递减计数器,指出共享状态的用户少了一个。如果计数器变为 0,则析构函数释放状态。
  4. 拷贝赋值运算符递增右侧运算对象的计数器,递减左侧运算对象的计数器。如果左侧对象的计数器变为 0,意味着它的共享状态没有用户了,拷贝赋值运算符就必须销毁状态。

C++简单Vector类的实现

之前写过一个简单String类的实现,这次再写写简单Vector类的实现,主要参照《C++ Primer(第5版)》第 13 章的一个实现,做了一些简化和修改。我们知道new有一些灵活性上的局限,它将内存分配和对象构造组合在了一起,当分配一大块内存时,我们通常计划在这块内存上按需构造对象,标准库allocator类定义在memory中,它帮助我们将内存分配和对象构造分离开来。下面是实现代码,主要使用allocator而不是new分配内存:

图 1:Vector 内存布局

The NIST Definition of Cloud Computing(翻译)

云计算是一种模型,它实现了无处不在的、便捷的、可通过网络按需访问的共享可配置计算资源池(例如网络、服务器、存储、应用程序和服务等资源),并在最小化管理开销或与服务提供商交互的前提下,实现这些资源的快速分配和释放。云计算模型有五个基本特性、三种服务模型和四种部署模型。

基本特征(Essential Characteristics)

  1. On-demand self-service(按需自助服务):不需要与服务提供商进行繁琐的交互, 消费者就可以单方面按需取用计算资源, 例如服务器时间和网络存储。
  2. Broad network access(带宽网络访问):各种各样的瘦或胖客户端平台(例如移动电话、平板电脑、笔记本电脑和工作站)都能使用标准机制通过网络访问资源。
  3. Resource pooling(资源池化):通过使用多租户模型,提供商的计算资源池可以服务于各种消费者,并根据他们的需求动态分配和重新分配不同的物理和虚拟资源。这些资源感觉上是与位置无关的,因为消费者通常无法控制或知晓资源的精确位置,但是他们可以指定更高抽象层面上的位置(例如国家、洲或者数据中心)。这些资源可能包括存储、处理器、内存和网络带宽。
  4. Rapid elasticity(快速弹性化):弹性地提供和释放计算能力以快速伸缩匹配等量的需求,这种伸缩在某些情况下是自动的。对消费者来说,可供调配的资源总是无限可用的,并且可在任意时间使用任意数量的资源。
  5. Measured service(服务可度量):通过利用与服务匹配的抽象层次的的度量机制(例如存储、处理器、带宽以及活跃用户帐户数),云计算系统能够自动控制并优化资源的使用。同时能够监控、控制和报告资源使用率,为服务提供商和消费者提供透明的服务。

C++与类型转换有关的关键字

我们知道,C++ 有四个与类型转换有关的关键字:const_cast、dynamic_cast、static_cast 和 reinterpret_cast,很容易混淆它们各自的用法,下面我来简单总结一下每个关键字的使用场景(原则上尽量不用类型转换操作,但是不得不用时也尽量使用这几个新式的转型操作,因为它们分工比较明确且容易识别):

1. const_cast 关键字

用途:转掉对象的 const 属性或者 volatile 属性,也是唯一能做到这一点的新式转型操作:

const int constant = 42; // local const
constant = 0; // error: read-only variable is not assignable
const_cast<int&>(constant) = 0; // normal expression
cout << constant << endl; // 42
cout << *(&constant) << endl; // 0