class Clock { public: Clock(int h, int m, int s); Clock(); //默认构造函数 void setTime(int h, int m, int s); void showTime(); private: int hour, minute, second; };
lst = [] for i in arange(5): def f (): print (i) print (f) lst.append(f)
for f in lst: f()
输出为
1 2 3 4 5 6 7 8 9 10
<function f at 0x000001E36692FE58> //函数对象是动态生成的 <function f at 0x000001E366949048> <function f at 0x000001E36694E798> <function f at 0x000001E36694E4C8> <function f at 0x000001E36694E708> 4 4 4 4 4
PyObject * PyWeakref_NewRef(PyObject *ob, PyObject *callback) { /*PyWeakReference是一个弱引用对象,result做临时存储*/ PyWeakReference *result = NULL; PyWeakReference **list; PyWeakReference *ref, *proxy; /*检查当前对象类型是否支持弱引用*/ if (!PyType_SUPPORTS_WEAKREFS(Py_TYPE(ob))) { PyErr_Format(PyExc_TypeError, "cannot create weak reference to '%s' object", Py_TYPE(ob)->tp_name); return NULL; } /*获取弱引用链表指针*/ list = GET_WEAKREFS_LISTPTR(ob); /*根据*list,给 ref 和 proxy 赋值*/ get_basic_refs(*list, &ref, &proxy); if (callback == Py_None) callback = NULL; if (callback == NULL) /* return existing weak reference if it exists */ result = ref; if (result != NULL) /*给当前weak reference引用加1*/ Py_INCREF(result); else { /* Note: new_weakref() can trigger cyclic GC, so the weakref list on ob can be mutated. This means that the ref and proxy pointers we got back earlier may have been collected, so we need to compute these values again before we use them. 使用之前,先确认ob对象没有被析构 */ result = new_weakref(ob, callback); if (result != NULL) { get_basic_refs(*list, &ref, &proxy); if (callback == NULL) { if (ref == NULL) insert_head(result, list); else { /* Someone else added a ref without a callback during GC. Return that one instead of this one to avoid violating the invariants of the list of weakrefs for ob. */ Py_DECREF(result); Py_INCREF(ref); result = ref; } } else { PyWeakReference *prev;
>>> from socket import * >>> s = socket(AF_INET, SOCK_STREAM) >>> ref_s = weakref.ref(s) >>> ref_s <weakref at 0x7f9b0316d3c0; to '_socketobject' at 0x7f9b0310b910> >>> s <socket._socketobject object at 0x7f9b0310b910> >>> proxy_s = weakref.proxy(s) >>> proxy_s <weakproxy at 0x7f9b03117208 to _socketobject at 0x7f9b0310b910> >>> >>> ref_s.close() # 不能直接调用对象方法 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'weakref' object has no attribute 'close'
>>> ref_s().close() # 不能直接调用对象方法,要加上()
>>>
>>> proxy_s.close() # 可以直接调用对象方法
>>>
>>> sys.getrefcount(s)
2
>>> ref_s
<weakref at 0x7f9b0316d3c0; to '_socketobject' at 0x7f9b0310b910>
>>> r = ref_s()
>>> r.close()
>>> sys.getrefcount(s)
3
>>> ref_s
<weakref at 0x7f9b0316d3c0; to '_socketobject' at 0x7f9b0310b910>
>>> del ref_s
>>> ref_s
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'ref_s' is not defined
>>>
由于 C 语言中 数组长度不是类型信息,我们可以
根据实际需要为 ob_digit 数组分配足够的内存,并将其当成长度为 n
的数组操作。这也是 C 语言中一个常用的编程技巧。长度信息在
PyVarObject(PyVarObject比PyObjcet多了个ob_size字段,详细定义可以看[python源码分析]
1.对象)中的ob_size中。
/* Ensure a is the larger of the two: */ if (size_a < size_b) { /*如果 a 数组长度比较小,将 a 、 b 交换,数组长度较大的那个在前面*/ { PyLongObject *temp = a; a = b; b = temp; } { Py_ssize_t size_temp = size_a; size_a = size_b; size_b = size_temp; } } /*创建新整数对象,用于保存计算结果(注意到长度必须比 a 和 b 都大一,因为可能有进位)*/ z = _PyLong_New(size_a+1);
if (z == NULL) return NULL; /*遍历 b 底层数组,与 a 对应部分相加并保存到 z 中,需要特别注意进位计算*/ for (i = 0; i < size_b; ++i) { carry += a->ob_digit[i] + b->ob_digit[i]; z->ob_digit[i] = carry & PyLong_MASK; carry >>= PyLong_SHIFT; } /*遍历 a 底层数组剩余部分,与进位相加后保存到 z 中,同样需要特别注意进位计算*/ for (; i < size_a; ++i) { carry += a->ob_digit[i]; z->ob_digit[i] = carry & PyLong_MASK; carry >>= PyLong_SHIFT; } /*将进位写入 z 底层数组最高位单元中*/ z->ob_digit[i] = carry; /*去除计算结果 z 底层数组中前面多余的零,因为最后的进位可能为零*/ return long_normalize(z); }
ps工具标识进程的5种状态码: - D 不可中断 uninterruptible sleep
(usually IO) - R 运行 runnable (on run queue) - S 中断 sleeping - T 停止
traced or stopped - Z 僵死 a defunct (”zombie”) process
F 代表这个程序的旗标 (flag), 4 代表使用者为 super user S 代表这个程序的状态 (STAT),关于各 STAT 的意义将在内文介绍 UID 程序被该 UID 所拥有 PID 进程的ID PPID 则是其 上级父程序的ID C CPU 使用的资源百分比 PRI 这个是 Priority (优先执行序) 的缩写,详细后面介绍 NI 这个是 Nice 值,在下一小节我们会持续介绍 ADDR 这个是 kernel function,指出该程序在内存的那个部分。如果是个 running的程序,一般就是 “-“ SZ 使用掉的内存大小 WCHAN 目前这个程序是否正在运作当中,若为 - 表示正在运作 TTY 登入者的终端机位置 TIME 使用掉的 CPU 时间。 CMD 所下达的指令为何