类比对象大,对象是类底下的一个实例,这些对象都有一些共同特征,因此归为一类。
一.类
类定义了对象的属性(特征)和方法(功能)。
1 2 3 4 5 6 7 8 9 10 11 12 13
| class Arknights: atk = None fangyu = None zudang = None cost = None def op(): print('攻击') print(type(Arknights))
print(type(list))
|
输出:
1 2
| <class 'type'> <class 'type'>
|
二.对象
2.1 创建对象并访问
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class Arknights: atk = None fangyu = None zudang = None cost = None def op(): print('攻击') Ace = Arknights() print(type(Ace))
print(Ace.atk) print(Ace.fangyu) print(Ace.zudang) print(Ace.cost)
Ace.op()
|
输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <class '__main__.Arknights'> None None None None
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[16], line 20 17 print(Ace.cost) 19 # 访问方法,隐式操作,op()会将创建的对象当作参数传入即op(Ace) ---> 20 Ace.op()
TypeError: Arknights.op() takes 0 positional arguments but 1 was given
|
正确做法:
1 2 3 4 5 6 7 8 9 10 11 12 13
| class Arknights: atk = None fangyu = None zudang = None cost = None def op(self): print('攻击') Ace = Arknights() print(type(Ace)) Ace.op()
|
输出:
1 2
| <class '__main__.Arknights'> 攻击
|
2.2 两个同类对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class Arknights: atk = None fangyu = None zudang = None cost = None def op(): print('攻击')
Ace = Arknights() Ew = Arknights()
print(id(Ace)) print(id(Ew))
|
输出:
1 2
| 1683888245072 1683888245408
|
2.3 创建对象时初始化成员值
1 2 3 4 5 6 7 8 9 10
| class Arknights: def __init__(self,atk,fangyu,zudang,cost): print(atk,fangyu,zudang,cost) Ace = Arknights(100,100,1,8)
print(Ace.atk)
|
输出:
1 2 3 4 5 6 7 8 9 10 11
| 100 100 1 8 <__main__.Arknights object at 0x000001880F8D0C20>
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) Cell In[31], line 10 8 Ace = Arknights(100,100,1,8) 9 print(Ace) ---> 10 print(Ace.atk)
AttributeError: 'Arknights' object has no attribute 'atk'
|
正确做法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class Arknights: def __init__(self,atk,fangyu,zudang,cost): self.Atk = atk self.Fangyu = fangyu self.Zudang = zudang self.Cost = cost Ace = Arknights(100,100,1,8) print(Ace.Atk) print(Ace.Fangyu) print(Ace.Zudang) print(Ace.Cost)
|
输出:
2.4 既有创建时就相同的值,也可以初始化一些属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class Arknights: life = 1 def __init__(self,atk,fangyu,zudang,cost): self.Atk = atk self.Fangyu = fangyu self.Zudang = zudang self.Cost = cost Ace = Arknights(111,55,2,8) ew = Arknights(100,50,1,20)
print(Ace.life) print(Ace.Atk) print() print(ew.life) print(ew.Atk) print()
|
输出:
2.5 更改对象属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class Arknights: life = 1 def __init__(self,atk,fangyu,zudang,cost): self.Atk = atk self.Fangyu = fangyu self.Zudang = zudang self.Cost = cost def change_life(self,num): self.life = num Ace = Arknights(111,55,2,8) ew = Arknights(100,50,1,20)
Ace.life = 2 print(Ace.life) print(ew.life)
Ace.change_life(3) print(Ace.life)
|
输出:
注意,没有对象的话是不能直接访问属性的,不要跟函数包含函数搞混了。
1 2 3 4 5 6 7 8
| class Arknights: life = 1 def fun(self,x): if x == life: print('你死了') a = Arknights() a.fun(1)
|
输出:
1 2 3 4 5 6 7 8 9 10 11 12 13
| --------------------------------------------------------------------------- NameError Traceback (most recent call last) Cell In[53], line 9 6 print('你死了') 8 a = Arknights() ----> 9 a.fun(1)
Cell In[53], line 5, in Arknights.fun(self, x) 4 def fun(self,x): ----> 5 if x == life: 6 print('你死了')
NameError: name 'life' is not defined
|
正确做法:
1 2 3 4 5 6 7 8
| class Arknights: life = 1 def fun(self,x): if x == self.life: print('你死了') a = Arknights() a.fun(1)
|
输出:
2.6 共享方法
有一个有趣的问题,既然创建多个对象,里面的属性和方法都一样,那python的设计者有没有必要将每个对象里都放一次方法呢?
答案是否定的,他们都有相同的属性,但共享方法,方法是单独放在一个空间里的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class Arknights: life = 1 def __init__(self,atk,fangyu,zudang,cost): self.Atk = atk self.Fangyu = fangyu self.Zudang = zudang self.Cost = cost def change_life(self,num): self.life = num Ace = Arknights(111,55,2,8) ew = Arknights(100,50,1,20)
print(id(Ace.change_life),id(ew.change_life))
|
输出:
1
| 1683892761472 1683892761472
|
结果就是俩函数地址一样,也就是方法的位置是固定的,是共享的。
—————————————————————————————————————————————————————————————————————————
然后我们来看看方法的使用,类中方法中也可以访问另一个方法,用self
来访问。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class Arknights: def fn(self,x): print('fn') self.fn1(x) def fn1(self,y): print(y) print('fn1') Ace = Arknights() Ace.fn(1)
|
输出:
三.类属性
就是一个类共同的属性,是在一开始就决定好的东西。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class arknights: x = 1 def fun(self): print('fun') a = arknights()
print(arknights.x) print(a.x)
a.fun() arknights.fun()
|
输出:
1 2 3 4 5 6 7 8 9 10 11 12
| 1 1 fun
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[56], line 15 13 # 也可以通过类来访问其中的方法,但这不是类方法 14 a.fun() ---> 15 arknights.fun()
TypeError: arknights.fun() missing 1 required positional argument: 'self'
|
正确做法:
输出:
注意:这里的123才是传进去的self
参数,直接用类来调用其中的方法是不可行的,一般传的都是类自己,比如这里可以是arknights.fun(arknights)。