Skip to content

Commit d97414e

Browse files
committed
add class and object
1 parent 3d9ce11 commit d97414e

1 file changed

Lines changed: 213 additions & 0 deletions

File tree

Class/class_and_object.md

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,215 @@
11
# 类和实例
22

3+
类是一个抽象的概念,我们可以把它理解为具有相同**属性****方法**的一组对象的集合,而实例则是一个具体的对象。我们还是先来看看在 Python 中怎么定义一个类。
4+
5+
这里以动物(Animal)类为例,Python 提供关键字 `class` 来声明一个类:
6+
7+
```python
8+
class Animal(object):
9+
pass
10+
```
11+
12+
其中,`Animal` 是类名,通常类名的首字母采用大写(如果有多个单词,则每个单词的首字母大写),后面紧跟着 `(object)`,表示该类是从哪个类继承而来的,所有类最终都会继承自 `object` 类。
13+
14+
类定义好了,接下来我们就可以**创建实例**了:
15+
16+
```python
17+
>>> animal = Animal() # 创建一个实例对象
18+
>>> animal
19+
<__main__.Animal at 0x1030a44d0>
20+
```
21+
22+
我们在创建实例的时候,还可以传入一些参数,以初始化对象的属性,为此,我们需要添加一个 `__init__` 方法:
23+
24+
```python
25+
class Animal(object):
26+
def __init__(self, name):
27+
self.name = name
28+
```
29+
30+
然后,在创建实例的时候,传入参数:
31+
32+
```python
33+
>>> animal = Aniaml('dog1') # 传入参数 'dog1'
34+
>>> animal.name # 访问对象的 name 属性
35+
'dog1'
36+
```
37+
38+
我们可以把 `__init__` 理解为对象的初始化方法,它的第一个参数永远是 `self`,指向创建的实例本身。定义了 `__init__` 方法,我们在创建实例的时候,就需要传入与 `__init__` 方法匹配的参数。
39+
40+
接下来,我们再来添加一个方法:
41+
42+
```python
43+
class Animal(object):
44+
def __init__(self, name):
45+
self.name = name
46+
def greet(self):
47+
print 'Hello, I am %s.' % self.name
48+
```
49+
50+
我们添加了方法 `greet`,看看下面的使用:
51+
52+
```python
53+
>>> dog1 = Animal('dog1')
54+
>>> dog1.name
55+
'dog1'
56+
>>> dog1.greet()
57+
Hello, I am dog1.
58+
```
59+
60+
现在,让我们做一下总结。我们在 Animal 类定义了两个方法:`__init__``greet``__init__` 是 Python 中的**特殊方法(special method)**,它用于对对象进行初始化,类似于 C++ 中的构造函数;`greet` 是我们自定义的方法。
61+
62+
注意到,我们在上面定义的两个**方法**有一个共同点,就是它们的第一个参数都是 `self`,指向实例本身,也就是说它们是和实例绑定的函数,这也是我们称它们为方法而不是函数的原因。
63+
64+
# 访问限制
65+
66+
在某些情况下,我们希望限制用户访问对象的属性或方法,也就是希望它是私有的,对外隐蔽。比如,对于上面的例子,我们希望 `name` 属性在外部不能被访问,我们可以**在属性或方法的名称前面加上两个下划线**,即 `__`,对上面的例子做一点改动:
67+
68+
```python
69+
class Animal(object):
70+
def __init__(self, name):
71+
self.__name = name
72+
def greet(self):
73+
print 'Hello, I am %s.' % self.__name
74+
```
75+
76+
```python
77+
>>> dog1 = Animal('dog1')
78+
>>> dog1.__name # 访问不了
79+
---------------------------------------------------------------------------
80+
AttributeError Traceback (most recent call last)
81+
<ipython-input-206-7f6730db631e> in <module>()
82+
----> 1 dog1.__name
83+
84+
AttributeError: 'Animal' object has no attribute '__name'
85+
>>> dog1.greet() # 可以访问
86+
Hello, I am dog1.
87+
```
88+
89+
可以看到,加了 `__``__name` 是不能访问的,而原来的 `greet` 仍可以正常访问。
90+
91+
需要注意的是,在 Python 中,以双下划线开头,并且以双下划线结尾(即 `__xxx__`)的变量是特殊变量,特殊变量是可以直接访问的。所以,不要用 `__name__` 这样的变量名。
92+
93+
另外,如果变量名前面只有一个下划线 `_`,表示**不要随意访问这个变量**,虽然它可以直接被访问。
94+
95+
# 获取对象信息
96+
97+
当我们拿到一个对象时,我们往往会考察它的类型和方法等,比如:
98+
99+
```
100+
>>> a = 123
101+
>>> type(a)
102+
int
103+
>>> b = '123'
104+
>>> type(b)
105+
str
106+
```
107+
108+
当我们拿到一个类的对象时,我们用什么去考察它呢?回到前面的例子:
109+
110+
```python
111+
class Animal(object):
112+
def __init__(self, name):
113+
self.name = name
114+
def greet(self):
115+
print 'Hello, I am %s.' % self.name
116+
```
117+
118+
- 第 1 招:使用 `type`
119+
120+
使用 `type(obj)` 来获取对象的相应类型:
121+
122+
```
123+
>>> dog1 = Animal('dog1')
124+
>>> type(dog1)
125+
__main__.Animal
126+
```
127+
128+
- 第 2 招:使用 `isinstance`
129+
130+
使用 `isinstance(obj, type)` 判断对象是否为指定的 type 类型的实例:
131+
132+
```
133+
>>> isinstance(dog1, Animal)
134+
True
135+
```
136+
137+
- 第 3 招:使用 `hasattr/getattr/setattr`
138+
139+
- 使用 `hasattr(obj, attr)` 判断对象是否具有指定属性/方法;
140+
- 使用 `getattr(obj, attr[, default])` 获取属性/方法的值, 要是没有对应的属性则返回 default 值(前提是设置了 default),否则会抛出 AttributeError 异常;
141+
- 使用 `setattr(obj, attr, value)` 设定该属性/方法的值,类似于 obj.attr=value;
142+
143+
看下面例子:
144+
145+
```python
146+
>>> hasattr(dog1, 'name')
147+
True
148+
>>> hasattr(dog1, 'x')
149+
False
150+
>>> hasattr(dog1, 'greet')
151+
True
152+
>>> getattr(dog1, 'name')
153+
'dog1'
154+
>>> getattr(dog1, 'greet')
155+
<bound method Animal.greet of <__main__.Animal object at 0x10c3564d0>>
156+
>>> getattr(dog1, 'x')
157+
---------------------------------------------------------------------------
158+
AttributeError Traceback (most recent call last)
159+
<ipython-input-241-42f5b7da1012> in <module>()
160+
----> 1 getattr(dog1, 'x')
161+
162+
AttributeError: 'Animal' object has no attribute 'x'
163+
>>> getattr(dog1, 'x', 'xvalue')
164+
'xvalue'
165+
>>> setattr(dog1, 'age', 12)
166+
>>> dog1.age
167+
12
168+
```
169+
170+
- 第 4 招:使用 `dir`
171+
172+
使用 `dir(obj)` 可以获取相应对象的**所有**属性和方法名的列表:
173+
174+
```python
175+
>>> dir(dog1)
176+
['__class__',
177+
'__delattr__',
178+
'__dict__',
179+
'__doc__',
180+
'__format__',
181+
'__getattribute__',
182+
'__hash__',
183+
'__init__',
184+
'__module__',
185+
'__new__',
186+
'__reduce__',
187+
'__reduce_ex__',
188+
'__repr__',
189+
'__setattr__',
190+
'__sizeof__',
191+
'__str__',
192+
'__subclasshook__',
193+
'__weakref__',
194+
'age',
195+
'greet',
196+
'name']
197+
```
198+
199+
# 小结
200+
201+
- 类是具有相同**属性****方法**的一组对象的集合,实例是一个个具体的对象。
202+
- 方法是与实例绑定的函数。
203+
- 获取对象信息可使用下面方法:
204+
- `type(obj)`:来获取对象的相应类型;
205+
- `isinstance(obj, type)`:判断对象是否为指定的 type 类型的实例;
206+
- `hasattr(obj, attr)`:判断对象是否具有指定属性/方法;
207+
- `getattr(obj, attr[, default])` 获取属性/方法的值, 要是没有对应的属性则返回 default 值(前提是设置了 default),否则会抛出 AttributeError 异常;
208+
- `setattr(obj, attr, value)`:设定该属性/方法的值,类似于 obj.attr=value;
209+
- `dir(obj)`:可以获取相应对象的**所有**属性和方法名的列表:
210+
211+
# 参考资料
212+
213+
- [Python:类和对象object | Hom](http://gohom.win/2015/10/20/pyObject/)
214+
215+

0 commit comments

Comments
 (0)