python面向对象

来源:互联网 发布:mac系统怎么制作铃声 编辑:程序博客网 时间:2024/06/06 02:22

面向对象最重要的概念就是类(Class)和实例(Instance)

class Student(object):    pass
定义了一个Student类,继承自object类,没有属性和方法。
stu = Studeng()
stu.name = 'wst' #可以在创建实例的时候把一些属性在此时创建并赋值,但这并推荐,最好通过一个__init__方法,在创建实例的时候酒吧name赋值
例如:
class Student():
  __init__(self,name):
    self.name = name

stu = Student('wst')

print stu.name  #有了__init__方法就可以在实例化一个对象的时候初始化一些属性数据

这里还需要注意在定义类方法的时候必须在参数中顶一个self参数,但是实例化类的时候或者调用方法的时候并不需要传递这个参数,其他参数正常传递。


python中并没有访问控制关键字,但是可以在属性或方法前加上"__",这就代表了这是私有成员,只允许类内访问,外部不能访问。

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和score属性就是私有成员了,类外就不能访问到

stu = Student('Bart Simpson', 98)
stu.__name = '123' #此时会报错
此时外部代码要获取name和score可以在Student类中增加get_name,get_score方法(略)

需要注意,在python中,变量名类似__xxx__的,也就是双下划线开头结尾的是特殊变量,特殊变量可以直接访问,不是private变量,所以不能用__name__, __score__这样的变量名。

有些时候,你会看到以一个下划线开头的实例变量名,比如_name,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”。

双下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。不能直接访问__name是因为Python解释器对外把__name变量改成了_Student__name,所以,仍然可以通过_Student__name来访问__name变量。但是强烈建议不能这么干,因为不同版本的python解释器可能会吧__name改成不同的变量名。


继承,所有面向对象的语言都拥有的性质,最大的好处是子类获得了父类的全部功能(子类会获得父类的方法)。例如Animial(父类)实现了run()方法,Dog作为它的子类,什么事也没干,就自动拥有了run()方法。当然如果子类也可以重写(覆盖)父类的方法。

在python中isinstance()函数可以判断某一个变量是否是某一个类型。使用该函数可以判断一个子类对象是否是父类类型,答案是true,这就很好的解释了多态的性质。如果一个子类对象覆盖了父类方法,那么在调用该方法的时候就使用子类中的定义,而如果子类没有覆盖该方法,那么在调用的时候就使用父类的定义。这就是多态的本质。


如何获取对象信息? 

 ——使用type()函数

>>> type(123)<type 'int'>>>> type('str')<type 'str'>>>> type(None)<type 'NoneType'>

如果一个变量指向函数或者类,也可以用type()判断:

>>> type(abs)<type 'builtin_function_or_method'>>>> type(a)<class '__main__.Animal'>

但是type()函数返回的是什么类型呢?它返回type类型。如果我们要在if语句中判断,就需要比较两个变量的type类型是否相同:

>>> type(123)==type(456)True>>> type('abc')==type('123')True>>> type('abc')==type(123)False

但是这种写法太麻烦,Python把每种type类型都定义好了常量,放在types模块里,使用之前,需要先导入:

>>> import types>>> type('abc')==types.StringTypeTrue>>> type(u'abc')==types.UnicodeTypeTrue>>> type([])==types.ListTypeTrue>>> type(str)==types.TypeTypeTrue

最后注意到有一种类型就叫TypeType,所有类型本身的类型就是TypeType,比如:

>>> type(int)==type(str)==types.TypeTypeTrue

——使用istance()函数判断类型?

对于class的继承关系来说,使用type()就很不方便。我们要判断class的类型,可以使用isinstance()函数。isinstance()判断的是一个对象是否是该类型本身,或者位于该类型的父继承链上。

能用type()判断的基本类型也可以用isinstance()判断:

>>> isinstance('a', str)True>>> isinstance(u'a', unicode)True>>> isinstance('a', unicode)False

——使用dir()函数?

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

仅仅把属性和方法列出来是不够的,配合getattr()setattr()以及hasattr(),我们可以直接操作一个对象的状态:

>>> class MyObject(object):...     def __init__(self):...         self.x = 9...     def power(self):...         return self.x * self.x...>>> obj = MyObject()

紧接着,可以测试该对象的属性:

>>> hasattr(obj, 'x') # 有属性'x'吗?True>>> obj.x9>>> hasattr(obj, 'y') # 有属性'y'吗?False>>> setattr(obj, 'y', 19) # 设置一个属性'y'>>> hasattr(obj, 'y') # 有属性'y'吗?True>>> getattr(obj, 'y') # 获取属性'y'19>>> obj.y # 获取属性'y'19

如果试图获取不存在的属性,会抛出AttributeError的错误:

>>> getattr(obj, 'z') # 获取属性'z'Traceback (most recent call last):  File "<stdin>", line 1, in <module>AttributeError: 'MyObject' object has no attribute 'z'

可以传入一个default参数,如果属性不存在,就返回默认值:

>>> getattr(obj, 'z', 404) # 获取属性'z',如果不存在,返回默认值404404

也可以获得对象的方法:

>>> hasattr(obj, 'power') # 有属性'power'吗?True>>> getattr(obj, 'power') # 获取属性'power'<bound method MyObject.power of <__main__.MyObject object at 0x108ca35d0>>>>> fn = getattr(obj, 'power') # 获取属性'power'并赋值到变量fn>>> fn # fn指向obj.power<bound method MyObject.power of <__main__.MyObject object at 0x108ca35d0>>>>> fn() # 调用fn()与调用obj.power()是一样的81



0 0
原创粉丝点击