码迷,mamicode.com
首页 > 编程语言 > 详细

Python 面向对象编程

时间:2019-04-21 12:53:23      阅读:170      评论:0      收藏:0      [点我收藏+]

标签:for循环   增加   分数   []   ash   划线   start   参数   name   

 

1.类和实例

 1 #!/usr/bin/python3
 2 
 3 class Student(object):
 4 #表示该类从哪个类继承下来的,如没有合适的继承类,就是用object类
 5 #这是所有类最终都会继承的类
 6     def __init__(self,name,score):
 7         self.name = name
 8         self.score = score
 9     def print_score(self):
10         print(%s:%s % (self.name, self.score))
11 
12 b = Student(Chb, 100)   #创建实例
13 print(b.name)
14 print(b.score)
15 print(b.print_score())

技术图片

如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问

类有一个名为 __init__() 的特殊方法(构造方法),该方法在类实例化时会自动调用

类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称, 按照惯例它的名称是 self

self代表类的实例,而非类,表示创建的实例本身

 

2.获取对象信息

当我们拿到一个对象的引用时,如何知道这个对象是什么类型、有哪些方法呢?

使用type()

返回对应的class类型

技术图片

使用isinstance()

对于class的继承关系来说,使用type()就很不方便。isinstance()就可以告诉我们,一个对象是否是某种类型。

技术图片

总是优先使用isinstance()判断类型,可以将指定类型及其子类“一网打尽”。

使用dir()

如果要获得一个对象的所有属性和方法,可以使用dir()函数,它返回一个包含字符串的list

技术图片

 

__slots__

在Python中,定义一个class类并创建了一个class的实例后,可以给该实例绑定任何属性和方法,这是动态语言的灵活性

技术图片

但是,给一个实例绑定的方法,对另一个实例是不起作用的

技术图片

如果我们想要限制实例的属性怎么办?比如,只允许对Student实例添加nameage属性。

为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性

技术图片

由于‘score‘没有被放到__slots__中,所以不能绑定score属性,试图绑定score将得到AttributeError的错误。

使用__slots__要注意,__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的

 

@property

@property广泛应用在类的定义中,可以让调用者写出简短的代码,同时保证对参数进行必要的检查。把一个方法变成属性调用

 1 #!/usr/bin/python3
 2 
 3 class Student(object):
 4     @property
 5     def score(self):
 6         return self._score
 7     @score.setter
 8     def score(self, value):
 9         if not isinstance(value, int):
10             raise ValueError(分数必须是整数)
11         if value<0 or value>100:
12             raise ValueError(分数必需在0~100之间)
13         self._score = value
14 
15 s = Student()
16 s.score = 60
17 print(s.score)
18 print(------------------------------)
19 s.score = 999
20 print(s.score)

技术图片

 

多重继承

给一个类增加多个功能

class Dog(A, B, C):
    pass

 

定制类

非常方便生成特定的类

__str__   

打印自定义的实例

 1 #!/usr/bin/python3
 2 
 3 class Student(object):
 4     def __init__(self, name):
 5         self.name = name
 6     def __str__(self):
 7         return Student object (name:%s) % self.name
 8     __repe__ = __str__
 9 
10 s = Student(Chb)
11 print(s)

技术图片

 

 __iter__

如果一个类想被用于for ... in循环,类似list或tuple那样,就必须实现一个__iter__()方法,该方法返回一个迭代对象,然后,Python的for循环就会不断调用该迭代对象的__next__()方法拿到循环的下一个值,直到遇到StopIteration错误时退出循环。

 1 #!/usr/bin/python3
 2 
 3 class Fib(object):
 4     def __init__(self):
 5         self.a, self.b = 1,1
 6     def __iter__(self):
 7         return self  #实例本身就是迭代对象,故返自己
 8     def __next__(self):
 9         self.a, self.b = self.b, self.a+self.b
10         if self.a > 1000:  #退出循环条件
11             raise StopIteration()
12         return self.a
13         
14 for n in Fib():
15     print(n)

技术图片

 

 __getitem__

使自己定义的类型和list、dict没什么区别,如可以按索引取值、切片

 1 #!/usr/bin/python3
 2 
 3 class Fib(object):
 4     def __getitem__(self, n):
 5         if isinstance(n, int):  #n是索引的情况
 6             a, b = 1, 1
 7             for x in range(n):
 8                 a, b = b, a+b
 9             return a
10         if isinstance(n, slice):  #n是切片的情况
11             start = n.start
12             stop = n.stop
13             if start is None:  #如果开头没赋值 L[::] 则默认开始下标为0
14                 start = 0
15             a, b = 1, 1
16             L = []
17             for x in range(stop):
18                 if x >= start:
19                     L.append(a)
20                 a, b = b, a+b
21             return L
22         
23 f = Fib()
24 print(f[10])
25 print(f[0:5])

技术图片

 

__getattr__

正常情况下,当我们调用类的方法或属性时,如果不存在,就会报错。

要避免这个错误,可以写一个__getattr__()方法,动态返回一个属性。

 1 #!/usr/bin/python3
 2 
 3 class Student(object):
 4     def __init__(self):
 5         self.name = aaa
 6     def __getattr__(self, attr):
 7         if attr == score:
 8             return 60
 9             
10 s = Student()
11 print(s.name)
12 print(s.score)

技术图片

当调用不存在的属性时,比如score,Python解释器会试图调用__getattr__(self, ‘score‘)来尝试获得属性,这样,我们就有机会返回score的值

 

__call__

直接对实例进行调用

 1 #!/usr/bin/python3
 2 
 3 class Student(object):
 4     def __init__(self, name):
 5         self.name = name
 6     def __call__(self):
 7         print(My name is %s % self.name)
 8             
 9 s = Student(chb)
10 print(s())

技术图片

 

Python 面向对象编程

标签:for循环   增加   分数   []   ash   划线   start   参数   name   

原文地址:https://www.cnblogs.com/bfcs/p/10744665.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!