- Homepage: http://www.python-excel.org/
- Pip install:https://pypi.python.org/pypi/xlrd
- Document:http://xlrd.readthedocs.io/en/latest/
在C++ 中,遍历一个容器的方法一般是这样的:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#include <iostream> #include <vector> int main(void) { std::vector<int> vec; //do sth std::vector<int>::iterator it = vec.begin(); for(; it != vec.end(); ++it) { std::cout<< *it <<std::endl; } return 0; } |
对STL比较熟悉的程序员肯定还知道在 <algorithm> 中有一个 for_each 算法,可以用来完成上述功能:
1 2 3 4 5 6 7 |
int main(void) { std::vector<int> vec; //do sth std::for_each(vec.begin(), vec.end(), [](auto val){std::cout<<val<<std::endl;}); return 0; } |
这里借助了 auto 关键字和 lambda 表达式简化了操作。 std::for_each 比起前面 for 循环,最大的好处是不再需要关注迭代器的概念,而只需要关心容器中的元素类型即可。 但这两种方法,都必须显式的给出容器有开头和结尾(begin,end).这是因为上面的两种方法都不是基于范围(range)来设计的. 范围的概念在很多高级语言中都有涉及。例如下面这段 python 代码:
1 2 3 |
arr = [1,2,3,4,5] for n in arr: print n |
在这种循环中,不再需要关心容器的两端,循环会自动以容器的范围进行展开。而且这种语法可以清楚地表明它的意义。使用这种方式进行循环无疑会使编码和维护更加简便。 现在,c++11 可有了基于范围的 for 循环:
1 创建类
使用 class 关键字来创建一个类。
1 2 3 |
class ClassName: '类的注释' class_suite #类体 |
类的注释可由 ClassName.__doc__ 来查看。class_suite 由类的成员、方法、属性组成
实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#-*- coding:utf-8 -*- class Student: '学生' def __init__(self, name,sex,num): self.name = name self.sex = sex self.num = num def displayInfo(self): print "Name:",self.name,",Sex:",self.sex,",Num:",self.num def __del__(sefl): class_name = self.__class__.__name__ print class_name,'Deleted' |
- __init__() 可以看作是类的构造函数。(其实类的构造函数是 __new__ ,它是一个类方法 ,在类的实例初始化之前调用。__init__ 实际是类的初始化函数)
- self 代表类的实例,类的方法必须有一个额外的形参,按惯例它的名称为self,但在调用时不必传入该参数。
- __del__() 是类的析构函数,在对象被销毁的时候调用。
2 类的实例
要创建一个类的实例,可以调用该一特殊的函数来完成。该函数的名称为类的名称,参数为该类的 __init__()的参数。
1 2 3 4 5 6 7 8 9 10 |
>>> from Student import Student >>> s = Student('A',1,1) >>> s.displayInfo() Name: A ,Sex: 1 ,Num: 1 >>> print s.name #属性 A >>> print s.__doc__ 学生 >>> print Student.__doc__ 学生 |
还可以使用下列函数来访问属性:
- getattr(obj,name[,default]) 访问对象的属性
- hasattr(obj,name) 检查是否存在一个属性
- setattr(obj,name,value) 设置一个改改。如果不存在,则创建之
- delattr(obj,name) 删除一个属性
数据类型
1.long long
long long 数据类型,提供至少 64 位的整型数据。
2.nullptr
C++11 推荐使用 nullptr 表示空指针,不再推荐使用 NULL 或 0 表示空指针。 NULL为从 C 语言中引进的,在 C 语言中一般被定义为宏:
1 2 3 4 5 |
#ifdef __cplusplus #define NULL 0 #else #define NULL ((void*)0) #endif |
在 C 语言中,可以将 void* 隐式转换为任意指针类型,而在 C++ 中,可以为任意类型的指针赋 0 值。所以 c++ 将 NULL 定义为 0. nullptr 是指针类型(nullptr_t),该类型的对象不允许转换到非指针类型。
3.contexpr
1).const expression 常量表达式
是指值不会改变且在编译过程中就能得到计算结果的表达式。字面量属于常量表达式,使用常量表达式初始化的 const 对象也是常量表达式。一个对象或表达式是不是常量表达式要由它的数据类型和初始值共同决定:
1 2 3 4 |
const int max = 1024; // max 是常量表达式 const int min = max - 1000; // min 是常量表达式 int nsize = 64; // nsize 不是常量表达式 const int sz = nsize + 1; // nsize 不是常量表达式 |
尽管 size 变量的初始化值是字面常量 ,但是它的定义数据类型是 int 而不是 const int 。 尽管 sz 定义为 const int ,但其值需要运行时才能得到,所以它也不是常量表达式。
2).constexpr 变量
C++11 中,允许将变量声明为 constexpr 类型,以便由编译器检查变量是否为一个常量表达式:声明为 constexpr 的变量一定是一个常量 ,且必须使用常量表达式初始化:
1 2 3 |
constexpr int max = 1024; //是常量表达式 constexpr int min = max - 1000; //是常量表达式 constexpr int sz = get_size(); //只有当 get_size() 是常量表达式时,定义才是常量表达式 |
3).constexpr 函数
constexpr 可用于指示函数是一个常量表达式。这需要满足:
- 返回值类型是字面值类型
- 形参类型是字面值类型
- 函数体中必须有且仅有一条 return 语句
4).constexpr 与 const
1 2 |
const int* p = nullptr; //p 是一个指向整型常量的指针 constexpr int* q = nullptr; //q 是一个指向整型的常量指针 |
这里的 p 和 q 本质是不一样的。指针 p 指向的整数是常量,而指针 q 本身是常量,其指向的整数则可以不是常量:
1 2 3 4 |
*p = 5; //错误 ,p 指向的整数是一个常量,即 *p 是不可修改的 p = new int(0); //正确 , p 是可以修改的 *q = 5; //正确 , q 指向的整数的值是可以修改的 q = new int(0); //错误 , q 是一个常量表达式,不可修改 |
其中的关键在于constexpr把它所定义的对象置为了顶层const.
4.noexcept
noexcept 指示一个函数不会抛出异常。如果一个使用 noexcept 修饰的函数内部抛出了异常,编译器并不会报错,但