类与对象
类和对象
类就是抽象的概念
对象就是类生成的具体事例
属性就是类和对象所具有的事物的性质
方法就是类和对象的执行函数
例子:
人是一个抽象的类
你我他是类具体而成的对象
属性就是人这个类所具有的性质,比如说,身高体重头发颜色单双眼皮
方法就是人或者你我他能干的事,比如说,站,坐,躺,吃,喝
1 class Cat: 2 #属性 3 #方法 4 def xxx(self):#此处必须写self ====>同等于this指针指向当前的对象 5 print "123" 6 7 redcat=Cat() 8 #与c语言不同之处,可以直接添加,而不需要在类里面定义 9 redcat.name="redcat"
__init__()函数
__init__的执行过程
1. 创建一个对象
2. python会自动调用__init__方法
3. 返回创建的对象的引用给对象
什么是引用,可以理解为当前这个对象是放在内存中的,我们找到这个内存,把这个内存的编号给了贴上这个对象的“标签”
(偷懒拷贝了一下)
1 class Cat: 2 #属性 3 #方法 4 def xxx(self):#此处必须写self ====>同等于this指针指向当前的对象 5 print "123" 6 def __init__(self): 7 #__init__同等于c语言的构造函数 为默认
或许你不知道什么事构造函数,这没什么关系,名字而已,理解它就行了。
例如以下代码
1 class Cat(): 2 def __init__(self,new_name,new_age) 3 self.name=new_name 4 self.age=new_age
1 redcat=Cat("redcat",1) 2 bluecat=Cat("lanmao",2)
此时
cat1=Cat(参数1,参数2)
自动调用__init__函数
添加属性
当前对象name=参数1
当前对象age=参数2
相信很好理解吧。
__str__()函数
就上面那个例子而言,假如我们生成了对象redcat和bluecat,此时我们
print(redcat) print(bluecat)
当然会报错
除非我们使用了这个函数
def __str__(self) return 你想打印出来的话(把类的属性用上,形如self.xxx 。当然不用也可以)
然后print这个对象,就会出现上面那句话了
例子
1 class Student: 2 def __init__(self,new_name,new_age,new_ID) 3 self.name=new_name 4 self.age=new_age 5 self.ID=new_ID 6 7 def __str__(self) 8 return "%s的年龄是%s,学号是%s"%(self.name,self.age,self.ID) 9 10 11 #然后我们生成对象 12 13 xiaoming=Student(xiaoming,12,1) 14 15 #打印小明的信息 16 17 print(xiaoming)
那么此时假如小明有一只猫呢
我们可以这样(继续偷懒,复制上面的代码)
1 class Student: 2 def __init__(self,new_name,new_age,new_ID,new_cat): 3 self.name=new_name 4 self.age=new_age 5 self.ID=new_ID 6 self.cat=new_cat 7 def __str__(self): 8 message="%s的年龄是%s,学号是%s"%(self.name,self.age,self.ID) 9 message+=",拥有的猫是%s,猫的年龄是%s" %(self.cat.name,self.cat.age) 10 return message 11 12 13 14 class Cat(): 15 def __init__(self,new_name,new_age): 16 self.name=new_name 17 self.age=new_age 18 19 tom=Cat("tom",1) 20 21 xiaoming=Student("xiaoming",12,1,tom) 22 23 print(xiaoming)
更好一点的表达
当我们定义一个类,生成一个对象后,想让这个对象有自己的属性。
我们可以这样
1 class Cat:
2 pass
3
4 cat1=Cat()
5
6 cat1.name="虹猫"
7 cat1.age=1
或者这样
1 class Cat:
2 pass
3
4
5 cat1=Cat()
6
7 cat1.get_name()
8 cat1.get_age()
那么两种方法当然是有去别的,孰优孰劣呢
假设这时我们再生成一个对象
1 cat2=Cat()
2
3 cat2.age=-1
从语法上是正确的,但逻辑上并不对
所以推荐使用通过函数来获得属性
直接赋值存在一定的风险
更完美的表达应该是这样:
1 class Cat:
2 def get_name(self,new_name):
3 self.name=new_name
4 def get_age(self,new_age):
5 if new_age<0 or new_age >20
6 new_age=0
7 self.age=new_age
私有方法
就是在方法前加两条下划线
需要满足一定的条件,才能使用其他的方法调用这个私有方法
才能使用这个私有方法
1 class Cat:
2 #私有方法
3 def __eat_fish():
4 print "猫在吃鱼"
5
6 def eat(self,age):
7 if age>=1 and age<5
8 self.__eat_fish()
9 elif age>=5
10 print "猫的年龄太大了,不能吃鱼"
11 else
12 print "猫的年龄太小了,不能吃鱼"
13
14 cat1=Cat()
15 cat1.eat(5)
__del__()函数
类似于c++的析构函数
在对象被彻底删除时(不是标签被删除)
引用计数为0时
一定会调用这个方法
1 class Cat:
2 #私有方法
3 def __del__():
4 print "猫死了"
5
6
7 cat1=Cat()
8 print "================================="
但是结果却是
===================================
猫死了
因为程序结束,内存释放了
但是假如代码变成这样
class Cat:
#私有方法
def __del__(self):
print "猫死了"
print "==============================="
cat1=Cat()
del cat1
print "==============================="
cat1=Cat()
cat2=cat1
del cat1
print "==============================="
del cat1
结果却是因为引用计数不为0,前面已经说过引用的问题,这里就不多讲了。
那么怎么测引用计数呢
1 impore sys
2 sys.getrefcount(要测的计数对象)
就会得到实际引用计数+1的结果。但当引用计数为0时,程序会抛出异常。
函数重写
python中的继承的函数重写
大概是介个样子
1 class A:
2 def a(self):
3 print "1"
4
5 class B(A):
6 def a(self):
7 print "2"
8
9 a=A()
10 a.a()
11 b=B()
12 b.a()
输出结果当然没有疑问,因为A中的a()方法在B中已经被重写了
那假如我铁了心就要调用那个怎么办呢
可以这样
1 class A:
2 def a(self):
3 print ("1")
4
5 class B(A):
6 def a(self):
7 A.a(self)
8 print ("2")
9
10 a=A()
11 a.a()
12 b=B()
13 b.a()
or这样
class A:
def a(self):
print ("1")
class B(A):
def a(self):
super().a()
print ("2")
a=A()
a.a()
b=B()
b.a()
一些想法
1 class A:
2 def a(self):
3 print ("1")
4
5 class B(A):
6 def a(self):
7 # super().a()
8 print ("2")
9
10 class C(B):
11 pass
12
13 a=A()
14 a.a()
15 b=B()
16 b.a()
17 c=C()
18 c.a()
结果是
1
2
2
1 class A:
2 def a(self):
3 print ("1")
4
5 class B(A):
6 def a(self):
7 # super().a()
8 print ("2")
9
10 class C(B):
11 pass
12
13 a=A()
14 a.a()
15 b=B()
16 b.a()
17 c=C()
18 c.a()
结果为
1
1
2
1
2
重写方法并不是这个子类重写,以后继承这个子类的方法都会被重写
那假如就想只用最开始方法怎么办
重写喽,或者未来我学到更好的办法再补上来
1 class A:
2 def a(self):
3 print ("1")
4 class B(A):
5 def a(self):
6 # super().a()
7 print ("2")
8
9 class C(B):
10 def a(self):
11 A().a()
12 pass
13 a=A()
14 a.a()
15 b=B()
16 b.a()
17 c=C()
18 c.a()
结果为
1
2
1
就又重写回来了

浙公网安备 33010602011771号