python学习笔记5 面向对象编程
2016-12-06 10:20
357 查看
面向对象编程
class后面紧接着是类名,即Student,类名通常是大写开头的单词,紧接着是(object),表示该类是从哪个类继承下来的,继承的概念我们后面再讲,通常,如果没有合适的继承类,就使用object类,这是所有类最终都会继承的类。
定义好了Student类,就可以根据Student类创建出Student的实例,创建实例是通过类名+()实现的:
传参数的构造函数 第一个参数必须是self,构造函数你仍然可以用默认参数、可变参数和关键字参数。
有些时候,你会看到以一个下划线开头的实例变量名,比如
双下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。不能直接访问
student 是类名
也可以获得对象的函数。然后在外面直接调用这个函数
MethodType就是给s绑定一个方法。
给一个实例绑定的方法,对另一个实例是不起作用的
为了给所有实例都绑定方法,可以给class绑定方法
使用
对象.setProperty
对象.getProperty
现在希望能用标准的
对象.property = 这样就要用property
birth是读写属性
age是只读属性
类的描述方法
如果一个类想被用于for … in循环,类似list或tuple那样,就必须实现一个
下面的代码就可以用中括号访问了
如果一个对象没有被访问的的方法那么就会尝试使用
这里可以直接返回一些补救措施
一个对象实例可以有自己的属性和方法,当我们调用实例方法时,我们用instance.method()来调用。能不能直接在实例本身上调用呢?类似instance()?在Python中,答案是肯定的。
class的名称;
继承的父类集合,注意Python支持多重继承,如果只有一个父类,别忘了tuple的单元素写法;
class的方法名称与函数绑定,这里我们把函数fn绑定到方法名hello上。
当我们写下metaclass = ListMetaclass语句时,魔术就生效了,它指示Python解释器在创建MyList时,要通过ListMetaclass.new()来创建,在此,我们可以修改类的定义,比如,加上新的方法,然后,返回修改后的定义。
new()方法接收到的参数依次是:
当前准备创建的类的对象;
类的名字;
类继承的父类集合;
类的方法集合。
class Student(object): pass
class后面紧接着是类名,即Student,类名通常是大写开头的单词,紧接着是(object),表示该类是从哪个类继承下来的,继承的概念我们后面再讲,通常,如果没有合适的继承类,就使用object类,这是所有类最终都会继承的类。
定义好了Student类,就可以根据Student类创建出Student的实例,创建实例是通过类名+()实现的:
传参数的构造函数 第一个参数必须是self,构造函数你仍然可以用默认参数、可变参数和关键字参数。
class Student(object): def __init__(self, name, score): self.name = name self.score = score
访问限制
如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以
__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问
class Student(object): def __init__(self, name, score): self.__name = name self.__score = score def print_score(self): print '%s: %s' % (self.__name, self.__score)
有些时候,你会看到以一个下划线开头的实例变量名,比如
_name,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”。
双下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。不能直接访问
__name是因为Python解释器对外把
__name变量改成了
_Student__name,所以,仍然可以通过
_Student__name来访问
__name变量
student 是类名
继承和多态
获取对象信息type()
isinstance()
对于class的继承关系来说,使用type()就很不方便。我们要判断class的类型,可以使用函数。dir()
如果要获得一个对象的所有属性和方法,可以使用dir()函数,它返回一个包含字符串的list,比如,获得一个str对象的所有属性和方法:getattr()、setattr()以及hasattr(),
仅仅把属性和方法列出来是不够的,配合getattr()、setattr()以及hasattr(),我们可以直接操作一个对象的状态:也可以获得对象的函数。然后在外面直接调用这个函数
动态添加功能
可以给一个对象动态的添加功能>>> def set_age(self, age): # 定义一个函数作为实例方法 ... self.age = age ... >>> from types import MethodType >>> s.set_age = MethodType(set_age, s, Student) # 给实例绑定一个方法 >>> s.set_age(25) # 调用实例方法 >>> s.age # 测试结果
MethodType就是给s绑定一个方法。
给一个实例绑定的方法,对另一个实例是不起作用的
为了给所有实例都绑定方法,可以给class绑定方法
>>> def set_score(self, score): ... self.score = score ... >>> Student.set_score = MethodType(set_score, None, Student)
使用slots
如果我们想要限制class的属性怎么办?比如,只允许对Student实例添加name和age属性。>>> class Student(object): ... __slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称 ...
使用
__slots__要注意,
__slots__定义的属性仅对当前类起作用,对继承的子类是不起作用的:
使用property
之前必须用对象.setProperty
对象.getProperty
现在希望能用标准的
.操作符进行操作
对象.property = 这样就要用property
class Student(object): @property def birth(self): return self._birth @birth.setter def birth(self, value): self._birth = value @property def age(self): return 2014 - self._birth
birth是读写属性
age是只读属性
多重继承
支持多重继承定制类
__str__
__repr__
也是
类的描述方法__iter__
如果一个类想被用于for … in循环,类似list或tuple那样,就必须实现一个__iter__()方法,该方法返回一个迭代对象,然后,Python的for循环就会不断调用该迭代对象的next()方法拿到循环的下一个值,直到遇到StopIteration错误时退出循环。
class Fib(object): def __init__(self): self.a, self.b = 0, 1 # 初始化两个计数器a,b def __iter__(self): return self # 实例本身就是迭代对象,故返回自己 def next(self): self.a, self.b = self.b, self.a + self.b # 计算下一个值 if self.a > 100000: # 退出循环的条件 raise StopIteration(); return self.a # 返回下一个值
__getitem__
下面的代码就可以用中括号访问了class Fib(object): def __getitem__(self, n): a, b = 1, 1 for x in range(n): a, b = b, a + b return a Fib()[5]
__getattr__
如果一个对象没有被访问的的方法那么就会尝试使用__getattr__(self, '方法名')来尝试获得属性
这里可以直接返回一些补救措施
__call__
一个对象实例可以有自己的属性和方法,当我们调用实例方法时,我们用instance.method()来调用。能不能直接在实例本身上调用呢?类似instance()?在Python中,答案是肯定的。class Student(object): def __init__(self, name): self.name = name def __call__(self): print('My name is %s.' % self.name) >>> s = Student('Michael') >>> s() My name is Michael.
元类
type()
动态生成新的类型>>> def fn(self, name='world'): # 先定义函数 ... print('Hello, %s.' % name) ... >>> Hello = type('Hello', (object,), dict(hello=fn)) # 创建Hello class >>> h = Hello() >>> h.hello() Hello, world. >>> print(type(Hello)) <type 'type'> >>> print(type(h)) <class '__main__.Hello'>
class的名称;
继承的父类集合,注意Python支持多重继承,如果只有一个父类,别忘了tuple的单元素写法;
class的方法名称与函数绑定,这里我们把函数fn绑定到方法名hello上。
metaclass
我们也可以使用元类动态创建一个类型# metaclass是创建类,所以必须从`type`类型派生: class ListMetaclass(type): def __new__(cls, name, bases, attrs): attrs['add'] = lambda self, value: self.append(value) return type.__new__(cls, name, bases, attrs) class MyList(list): __metaclass__ = ListMetaclass # 指示使用ListMetaclass来定制类
当我们写下metaclass = ListMetaclass语句时,魔术就生效了,它指示Python解释器在创建MyList时,要通过ListMetaclass.new()来创建,在此,我们可以修改类的定义,比如,加上新的方法,然后,返回修改后的定义。
new()方法接收到的参数依次是:
当前准备创建的类的对象;
类的名字;
类继承的父类集合;
类的方法集合。
相关文章推荐
- Python 学习笔记-面向对象编程
- 【Python学习笔记】面向对象编程:访问限制
- Python学习笔记13:Python面向对象编程
- Python学习笔记 === python面向对象编程
- Python的面向对象编程方式学习笔记
- python 学习笔记7 面向对象编程
- Python学习笔记09_面向对象编程Object Oriented Programming
- 【Python】学习笔记——-7.0、面向对象编程
- python2.7学习笔记(9) ——面向对象编程
- Python简明教程学习笔记5--面向对象编程
- 【Python学习笔记】面向对象编程:类和实例
- Python面向对象编程——学习笔记
- Python学习笔记--2--面向对象编程
- python学习笔记之面向对象编程特性(二)
- Python面向对象编程中关于类和方法的学习笔记
- 【Python学习笔记】面向对象编程
- 【Python学习笔记】面向对象编程:继承和多态
- python-学习笔记1-面向对象编程
- 『Python学习』python 核心编程——面向对象编程学习笔记