Python学习笔记(面向对象编程)
面向对象编程
1、类和实例
类是模板,实例是根据类创建的具体对象, 类中的函数可以在对象中调用,称为对象的方法(Method)。
例子,Student类:
class Student(object):
pass
Student是类名,object是继承的类,如果没有合适的继承类,就使用object类,这是所有类最终都会继承的类
实例通过类名+()创建,可以通过实例.属性的方式为实例绑定属性,也可以用特殊的方法__init__()在创建实例的时候,直接为实例绑定属性。
例子:
class Student(object):
def __init__(self, name, score): '''第一个参数永远是self,调用时不用传递,表示实例本身'''
self.name = name
self.score = score
>>> bart = Student('Bart Simpson', 59)'''self参数不用传入,传入了name和score'''
>>> bart.name
'Bart Simpson'
>>> bart.score
59
使用类的函数来调用类内部的数据,这种相当于把类内部的数据封装起来,可以调用但是不知道类的内部细节。还可以方便的给类增加新的方法。
2、访问限制
如果要让Class内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在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))
def get_name(self):#取得__name
return self.__name
def get_score(self):#取得__score
return self.__score
def set_score(self, score):#改变__score
self.__score = score
3、继承和多态
定义一个class的时候可以从现有的class继承,新的class是子类,被继承的是父类。子类拥有父类的全部方法,在子类中不重新定义父类的方法时,调用的时父类的方法,重新定义后调用的是子类的方法。
例子:
class Animal(object):
def run(self):
print('Animal is running...')
class Dog(Animal):
def run(self): #对父类的同名方法进行重新定义
print('Dog is running...')
>>>dog = Dog()
>>>dog.run()
Dog is running...
子类的数据类型和父类一样,如上例中,dog不但是Dog类型还是Animal类型,这样当函数的参数是Animal类型时也可以传入Dog类型的参数,按照Animal类型操作,因为Dog是Animal的子类,反之不行。这就是多态。
例子:
def run_twice(animal):
animal.run()
animal.run()
>>> run_twice(Animal())
Animal is running...
Animal is running...
>>> run_twice(Dog())#Dog也是Animal类型
Dog is running...
Dog is running...
静态语言VS动态语言
对于静态语言上例的函数run_twice必须传输Animal类和子类,例如java。
对于动态语言python,只要保证传入的对象有run()方法就行,不一定非得是Animal类或子类。
使用super(a_type, obj)子类可以调用父类的方法。
例子:
class A(object):
def add(self, m):
print('self is {0} @A.add'.format(self))
self.n += m
class B(A):
def add(self, x):
super(B, self).add(x) #调用了A.add(),但是调用时self依然指向B
4、获取对象信息
type(),判断基本数据类型可以直接写int,str等,但如果要判断一个对象是否是函数可以使用types模块中定义的常量。
例子:
>>> type(123)==type(456)
True
>>> type(123)==int
True
>>> type('abc')==type('123')
True
>>> type('abc')==str
True
>>> type('abc')==type(123)
False
>>> import types
>>> def fn():
... pass
...
>>> type(fn)==types.FunctionType
True
>>> type(abs)==types.BuiltinFunctionType
True
>>> type(lambda x: x)==types.LambdaType
True
>>> type((x for x in range(10)))==types.GeneratorType
True
能用type()判断的,也能用isinstance()判断,还可以判断一个变量是否是某些类型中的一种。
例子:
>>> isinstance([1, 2, 3], (list, tuple))#判断是否是list或tuple
True
使用dir()可以得一个对象的所有属性和方法。
使用内置函数getattr()、setattr()以及hasattr()可以获取,设置和判断对象是否含有某属性。
getattr(object, name[, default]) #返回对象属性值。
object -- 对象。
name -- 字符串,对象属性。
default -- 默认返回值,如果不提供该参数,在没有对应属性时,将触发 AttributeError。
setattr(object, name, value) #用于设置属性值,该属性不一定是存在的。如果属性不存在,会创建一个新的属性
object -- 对象。
name -- 字符串,对象属性。
value -- 属性值。
hasattr(object, name) #如果对象有该属性返回 True,否则返回 False。
object -- 对象。
name -- 字符串,属性名。
例子:
>>> getattr(obj, 'z', 404) # 获取属性'z',如果不存在,返回默认值404
404
>>> fn = getattr(obj, 'power') # 获取属性'power'并赋值到变量fn
>>> fn # fn指向obj.power
<bound method MyObject.power of <__main__.MyObject object at 0x10077a6a0>>
>>> fn() # 调用fn()与调用obj.power()是一样的
81
5、实例属性和类属性
在class中定义的属性,归类所有,但是类的所有实例都能访问到。如果实例的属性和class的属性同名,实例的属性将屏蔽class的属性。
class的属性在定义class的时候被创建,之后在创建class的实例时不会反复创建。
例子:
class Student(object):
count = 0
print('class')
def __init__(self,name):
self.__name=name
Student.count = Student.count+1 #每次创建实例时将类中的count+1
1、类和实例
类是模板,实例是根据类创建的具体对象, 类中的函数可以在对象中调用,称为对象的方法(Method)。
例子,Student类:
class Student(object):
pass
Student是类名,object是继承的类,如果没有合适的继承类,就使用object类,这是所有类最终都会继承的类
实例通过类名+()创建,可以通过实例.属性的方式为实例绑定属性,也可以用特殊的方法__init__()在创建实例的时候,直接为实例绑定属性。
例子:
class Student(object):
def __init__(self, name, score): '''第一个参数永远是self,调用时不用传递,表示实例本身'''
self.name = name
self.score = score
>>> bart = Student('Bart Simpson', 59)'''self参数不用传入,传入了name和score'''
>>> bart.name
'Bart Simpson'
>>> bart.score
59
使用类的函数来调用类内部的数据,这种相当于把类内部的数据封装起来,可以调用但是不知道类的内部细节。还可以方便的给类增加新的方法。
2、访问限制
如果要让Class内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在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))
def get_name(self):#取得__name
return self.__name
def get_score(self):#取得__score
return self.__score
def set_score(self, score):#改变__score
self.__score = score
3、继承和多态
定义一个class的时候可以从现有的class继承,新的class是子类,被继承的是父类。子类拥有父类的全部方法,在子类中不重新定义父类的方法时,调用的时父类的方法,重新定义后调用的是子类的方法。
例子:
class Animal(object):
def run(self):
print('Animal is running...')
class Dog(Animal):
def run(self): #对父类的同名方法进行重新定义
print('Dog is running...')
>>>dog = Dog()
>>>dog.run()
Dog is running...
子类的数据类型和父类一样,如上例中,dog不但是Dog类型还是Animal类型,这样当函数的参数是Animal类型时也可以传入Dog类型的参数,按照Animal类型操作,因为Dog是Animal的子类,反之不行。这就是多态。
例子:
def run_twice(animal):
animal.run()
animal.run()
>>> run_twice(Animal())
Animal is running...
Animal is running...
>>> run_twice(Dog())#Dog也是Animal类型
Dog is running...
Dog is running...
静态语言VS动态语言
对于静态语言上例的函数run_twice必须传输Animal类和子类,例如java。
对于动态语言python,只要保证传入的对象有run()方法就行,不一定非得是Animal类或子类。
使用super(a_type, obj)子类可以调用父类的方法。
例子:
class A(object):
def add(self, m):
print('self is {0} @A.add'.format(self))
self.n += m
class B(A):
def add(self, x):
super(B, self).add(x) #调用了A.add(),但是调用时self依然指向B
4、获取对象信息
type(),判断基本数据类型可以直接写int,str等,但如果要判断一个对象是否是函数可以使用types模块中定义的常量。
例子:
>>> type(123)==type(456)
True
>>> type(123)==int
True
>>> type('abc')==type('123')
True
>>> type('abc')==str
True
>>> type('abc')==type(123)
False
>>> import types
>>> def fn():
... pass
...
>>> type(fn)==types.FunctionType
True
>>> type(abs)==types.BuiltinFunctionType
True
>>> type(lambda x: x)==types.LambdaType
True
>>> type((x for x in range(10)))==types.GeneratorType
True
能用type()判断的,也能用isinstance()判断,还可以判断一个变量是否是某些类型中的一种。
例子:
>>> isinstance([1, 2, 3], (list, tuple))#判断是否是list或tuple
True
使用dir()可以得一个对象的所有属性和方法。
使用内置函数getattr()、setattr()以及hasattr()可以获取,设置和判断对象是否含有某属性。
getattr(object, name[, default]) #返回对象属性值。
object -- 对象。
name -- 字符串,对象属性。
default -- 默认返回值,如果不提供该参数,在没有对应属性时,将触发 AttributeError。
setattr(object, name, value) #用于设置属性值,该属性不一定是存在的。如果属性不存在,会创建一个新的属性
object -- 对象。
name -- 字符串,对象属性。
value -- 属性值。
hasattr(object, name) #如果对象有该属性返回 True,否则返回 False。
object -- 对象。
name -- 字符串,属性名。
例子:
>>> getattr(obj, 'z', 404) # 获取属性'z',如果不存在,返回默认值404
404
>>> fn = getattr(obj, 'power') # 获取属性'power'并赋值到变量fn
>>> fn # fn指向obj.power
<bound method MyObject.power of <__main__.MyObject object at 0x10077a6a0>>
>>> fn() # 调用fn()与调用obj.power()是一样的
81
5、实例属性和类属性
在class中定义的属性,归类所有,但是类的所有实例都能访问到。如果实例的属性和class的属性同名,实例的属性将屏蔽class的属性。
class的属性在定义class的时候被创建,之后在创建class的实例时不会反复创建。
例子:
class Student(object):
count = 0
print('class')
def __init__(self,name):
self.__name=name
Student.count = Student.count+1 #每次创建实例时将类中的count+1
评论
发表评论