概述
1、类的定义:
# _*_ coding:utf-8_*_
class Student(object):# 继承object类,不写也可以,不写就不能调用object类里面的方法,一般写上
def __init__(self, name, score):
self.name = name
self.score = score
def print_msg(self): # 没有返回值
print '姓名:%s ,分数:%s' % (self.name, self.score)
def return_name(self): # 有返回值
return '姓名:%s ,分数:%s' % (self.name, self.score)
if __name__ == "__main__":
s = Student("zhangsan",60) # 实例化一个对象
print Student # <class '__main__.Student'>
print s # <__main__.Student object at 0x0255A9D0>
print s.print_msg() # 姓名:zhangsan ,分数:60,None;注意还会打出一个None,因为这个方法没有返回值
print s.return_name() # 姓名:zhangsan ,分数:60,这个就没有None了
注意:
__init__方法的第一个参数永远是self,表示创建的实例本身,因此,在__init__方法内部,就可以把各种属性绑定到self,因为self就指向创建的实例本身。
2、类的访问限制(加__):
从前面Student类的定义来看,外部代码还是可以自由地修改一个实例的name、score属性
例如我可以 s.name = "lisi"
如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__
在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问。
修改如下:
class Student(object):# 继承object类,不写也可以,不写就不能调用object类里面的方法,一般写上
def __init__(self, name, score):
self.__name = name
self.__score = score
def print_msg(self):
print '姓名:%s ,分数:%s' % (self.__name, self.__score)
def return_name(self):
return '姓名:%s ,分数:%s' % (self.__name, self.__score)
# 这样在外部调用 s.name = "lisi"就无效了,确保了外部代码不能随意修改对象内部的状态,这样通过访问限制的保护,代码更加健壮。
如果外部代码要获取name和score怎么办?可以通过提供get set方法解决
例如:
class Student(object):# 继承object类,不写也可以,不写就不能调用object类里面的方法,一般写上
def __init__(self, name, score):
self.__name = name
self.__score = score
def print_msg(self):
print '姓名:%s ,分数:%s' % (self.__name, self.__score)
def return_name(self):
return '姓名:%s ,分数:%s' % (self.__name, self.__score)
def get_name(self):
return self.__name
def get_score(self):
return self.__score
def set_score(self, score): # 可以通过条件判断给定的参数是否合法
if 0 <= score <= 100:
self.__score = score
else:
raise ValueError('bad score')
#外面可以直接通过get_name() 和 get_score来访问内部数据。
特别注意:
a.在Python中,变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量。
所以,不能用__name__、__score__这样的变量名。
如果用__score__,在外部是可以通过 s.__score__访问到的。
b.有些时候,你会看到以一个下划线开头的实例变量名,比如_name,这样的实例变量外部是可以访问的.
但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”。
c.双下划线开头的实例变量是不是一定不能从外部访问呢?
其实也不是。不能直接访问__name是因为Python解释器对外把__name变量改成了_Student__name,所以,仍然可以通过_Student__name来访
例如:print s._Student__name # zhangsan
3、继承和多态:
class Animal(object): # 父类
def run(self):
print 'Animal running...'
def run_1(animal):
animal.run()
class Dog(Animal): # 子类
def run(self): # 重写方法
print 'Dog running...'
class Cat(Animal): # 子类
def run(self):
print 'Cat running...'
def test_extend():
dog = Dog()
dog.run() # Dog running...
cat = Cat()
cat.run() # Cat running...
# 多态,可以传入不同的对象,会自动调用对应对象的run方法
Animal.run_1(dog)
Animal.run_1(cat)
if __name__ == "__main__":
test_extend()
继承可以把父类的所有功能都直接拿过来,这样就不必重零做起,子类只需要新增自己特有的方法,也可以把父类不适合的方法覆盖重写;
注意调用父类的方法
class Dog(Animal):
def run(self):
print 'Dog running...'
super(Dog, self).run() # 通过Dog找到父类Animal,再将self传到父类初始化
4、获取对象的信息
a.type()
通过type可以判断一个对象的数据类型
import types
def test_type():
print type(123) # <type 'int'>
print type('str') # <type 'str'>
print type(None) # <type 'NoneType'>
print type('abc') == types.StringType # True
b.isinstance()
对于class的继承关系来说,使用type()就很不方便。我们要判断class的类型,可以使用isinstance()函数。
dog = Dog()
print isinstance(dog,Animal) # True
5、@property使用:
a.使用get set的问题?
在绑定属性时,如果我们直接把属性暴露出去,虽然写起来很简单,但是,没办法检查参数,导致可以把成绩随便改
例如:
s = Student()
s.score = 9999
为了限制score的范围,可以通过一个set_score()方法来设置成绩,再通过一个get_score()来获取成绩,这样,在set_score()方法里,就可以检查参数
例如:
class Student(object):
def get_score(self):
return self._score
def set_score(self, value):
if not isinstance(value, int):
raise ValueError('score must be an integer!')
if value < 0 or value > 100:
raise ValueError('score must between 0 ~ 100!')
self._score = value
但是,上面的调用方法又略显复杂,没有直接用属性这么直接简单。
b.@property解决方案
Python内置的@property装饰器就是负责把一个方法变成属性调用的。
例如:
class Studentt(object):
@property #修饰get方法
def score(self):
return self.__score
@score.setter #修饰set方法
def score(self, value):
if not isinstance(value, int):
raise ValueError('score must be an integer!')
if value < 0 or value > 100:
raise ValueError('score must between 0 ~ 100!')
self.__score = value
注意:还可以定义只读属性,只定义getter方法,不定义setter方法就是一个只读属性。
例如:
class Studentt(object):
@property # 只修饰get方法,没有修饰set方法
def score(self):
return self.__score
if __name__ == "__main__":
s = Studentt()
s.score = 60
print s.score
这样运行会报错,提示没有set属性
Traceback (most recent call last):
File "D:/test_class.py", line 96, in <module>
s.score = 60
AttributeError: can't set attribute
最后
以上就是娇气寒风为你收集整理的python面向对象的全部内容,希望文章能够帮你解决python面向对象所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复