Python基础与深入(二)

1 使用property创建可管理的对象属性

property可以让实例在形式上是属性访问,但实际上调用方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Circle2(object):
def __init__(self, radius):
self.radius = radius

def getRadius(self):
# return self.radius
return round(self.radius, 2) # 表示四舍五入后保留小数点后两位

def setRadius(self, value):
if not isinstance(value, (int, long, float)):
raise valueError('wrong type .')
self.radius = float(value)

def getArea(self):
return self.radius * 2 * pi

R = property(getRadius, setRadius)

r = Circle2(3.2)
print(r.R) # 自动调用getRadius
r.R = 5.4 # 自动调用setRadius
print(r.R) # 自动调用getRadius

2.类属性和实例属性

类属性:

是可在类的所有实例之间共享的值(也就是说,它们不是单独分配给每个实例的)。例如下例中,num_of_instance 就是类属性,用于跟踪存在着多少个Test 的实例。

实例属性:

实例化之后,每个实例单独拥有的变量。

1
2
3
4
5
6
7
8
9
10
11
12
13
class Test(object):
num_of_instance = 0
def __init__(self, name):
self.name = name
Test.num_of_instance += 1

if __name__ == '__main__':
print Test.num_of_instance # 0
t1 = Test('jack')
print Test.num_of_instance # 1
t2 = Test('lucy')
print t1.name , t1.num_of_instance # jack 2
print t2.name , t2.num_of_instance # lucy 2

补充的例子

1
2
3
4
5
6
7
8
9
class Person:
name="aaa"

p1=Person()
p2=Person()
p1.name="bbb"
print p1.name # bbb
print p2.name # aaa
print Person.name # aaa

这里p1.name="bbb"是实例调用了类属性,这其实和上面第一个问题一样,就是函数传参的问题,p1.name一开始是指向的类属性name="aaa",但是在实例的作用域里把类属性的引用改变了,就变成了一个实例属性,self.name不再引用Person的类属性name了.

可以看看下面的例子:

1
2
3
4
5
6
7
8
9
class Person:
name=[]

p1=Person()
p2=Person()
p1.name.append(1)
print p1.name # [1]
print p2.name # [1]
print Person.name # [1]

参考:http://stackoverflow.com/questions/6470428/catch-multiple-exceptions-in-one-line-except-block

3.Python自省

自省就是面向对象的语言所写的程序在运行时,所能知道对象的类型.简单一句就是运行时能够获得对象的类型.比如type(),dir(),getattr(),hasattr(),isinstance().

1
2
3
4
5
a = [1,2,3]
b = {'a':1,'b':2,'c':3}
c = True
print type(a),type(b),type(c) # <type 'list'> <type 'dict'> <type 'bool'>
print isinstance(a,list) # True

4.列表解析、集合解析

代码示例如下:

1
2
3
4
list1=[x for x in range(100) if x%2==0] #或 [x for x in range(0,100,2)]
#集合的列表生成式
s={1,34,5,-7,6,87,-8,-9,11}
print({x for x in s if x%3==0})

5.Python中单下划线和双下划线

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>> class MyClass():
... def __init__(self):
... self.__superprivate = "Hello"
... self._semiprivate = ", world!"
...
>>> mc = MyClass()
>>> print mc.__superprivate
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: myClass instance has no attribute '__superprivate'
>>> print mc._semiprivate
, world!
>>> print mc.__dict__
{'_MyClass__superprivate': 'Hello', '_semiprivate': ', world!'}

__foo__:一种约定,Python内部的名字,用来区别其他用户自定义的命名,以防冲突,就是例如__init__(),__del__(),__call__()这些特殊方法

_foo:一种约定,用来指定变量私有.程序员用来指定私有变量的一种方式.不能用from module import * 导入,其他方面和公有一样访问;

__foo:这个有真正的意义:解析器用_classname__foo来代替这个名字,以区别和其他类相同的命名,它无法直接像公有成员一样随便访问,通过对象名._类名__xxx这样的方式可以访问.

详情见:http://stackoverflow.com/questions/1301346/the-meaning-of-a-single-and-a-double-underscore-before-an-object-name-in-python

或者: http://www.zhihu.com/question/19754941

6.字典、列表、元组、集合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# 补充:集合的交集并集等操作
A=set([randint(1,20) for _ in range(10)])
B=set([randint(1,20) for _ in range(10)])
print(A&B,A|B,A-B,A^B) #交,并,差,补


from collections import namedtuple
Student = namedtuple('Student', ['name', 'age', 'sex', 'email'])
Jim = Student('Jim', 16, 'male', 'jim8721@gamil.com')
print(Jim.name)

# 使用zip将字典数据转化为元组
score = {
'LiLei': 79,
'Jim': 88,
'Lucy': 92
}
score4 = tuple(zip(score.values(),score.keys()))

# 字典排序
print(sorted(score.items(),key=lambda x:x[1])) #表示对生成的列表的元组索引第二位进行排序

# 字典补充 k,v交换
score2={v:k for k,v in score.items()}
score3=dict(zip(score2.values(),score2.keys()))


# 统计元素出现的频度
from collections import Counter, OrderedDict
from random import randint
import re

data = [randint(0, 20) for _ in range(30)] #产生30个0到20的随机整数
print(Counter(data))
print(Counter(data).most_common(3))

# 创建有序的字典
from functools import OrderedDict
od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])

元组和列表的同异

同:列表与元组都是容器,是一系列的对象。二者都可以包含任意类型的元素甚至可以是一个序列,还可以包含元素的顺序(不像集合和字典)。
元组属于不可变对象,列表属于可变对象,列表的很多方法不适用于元组;元组可哈希而列表不可哈希;元组占用空间更小,代码的语义更好理解再函数式编程较常用。

坚持原创技术分享,您的支持将鼓励我继续创作!