python面向对象简称,python面向对象语法

面向对象编程

面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。

在Python中,所有数据类型都可以视为对象,当然也可以自定义对象。自定义的对象数据类型就是面向对象中的类(Class)的概念

例如: 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))

bart = Student('Bart Simpson', 59)

lisa = Student('Lisa Simpson', 87)

bart.print_score()

lisa.print_score()

面向对象的三大特征:封装,继承,多态

1.1类和实例

class后面紧接着是类名,即Student,类名通常是大写开头的单词,紧接着是(object),表示该类是从哪个类继承下来的,通常,如果没有合适的继承类,就使用object类,这是所有类最终都会继承的类。

class Student(object):

pass

创建实例是通过类名+()实现的: >>> bart = Student()

>>> bart

>>> Student

可以看到,变量bart指向的就是一个Student的实例,后面的0x10a67a590是内存地址,每个object的地址都不一样,而Student本身则是一个类。

把一些我们认为必须绑定的属性强制填写进类中。通过定义一个特殊的__init__方法,在创建实例的时候,就等属性绑上去: class Student(object):

def __init__(self, name, score):

self.name = name

self.score = score

注意到__init__方法的第一个参数永远是self,表示创建的实例本身

有了__init__方法,在创建实例的时候,就不能传入空的参数了,必须传入与__init__方法匹配的参数,但self不需要传,Python解释器自己会把实例变量传进去

1.2访问限制

实例的变量名如果以__开头,就变成了一个私有变量(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))

>>> bart = Student('Bart Simpson', 59)

>>> bart.__name

Traceback (most recent call last):

File "", line 1, in

AttributeError: 'Student' object has no attribute '__name'

双下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。不能直接访问__name是因为Python解释器对外把__name变量改成了_Student__name,所以,仍然可以通过_Student__name来访问__name变量: >>> bart._Student__name

'Bart Simpson'

但是强烈建议你不要这么干,因为不同版本的Python解释器可能会把__name改成不同的变量名。

总的来说就是,Python本身没有任何机制阻止你干坏事,一切全靠自觉。

最后注意下面的这种错误写法: >>> bart = Student('Bart Simpson', 59)

>>> bart.get_name()

'Bart Simpson'

>>> bart.__name = 'New Name' # 设置__name变量!

>>> bart.__name

'New Name'

表面上看,外部代码“成功”地设置了__name变量,但实际上这个__name变量和class内部的__name变量不是一个变量!内部的__name变量已经被Python解释器自动改成了_Student__name,而外部代码给bart新增了一个__name变量。不信试试: >>> bart.get_name() # get_name()内部返回self.__name

'Bart Simpson'

而是通过get。set方法 def get_score(self):

return self.__score

def set_score(self, score):

self.__score = score

1.3继承和多态

例如 class Animal(object):

def run(self):

print('Animal is running...')

class Dog(Animal): #括号内是继承的对象

pass

class Cat(Animal):

pass

对于Dog来说,Animal就是它的父类,对于Animal来说,Dog就是它的子类。Cat和Dog类似。

继承有什么好处?最大的好处是子类获得了父类的全部功能。由于Animial实现了run()方法,因此,Dog和Cat作为它的子类,什么事也没干,就自动拥有了run()方法:

当子类和父类都存在相同的run()方法时,我们说,子类的run()覆盖了父类的run(),在代码运行的时候,总是会调用子类的run()。这样,我们就获得了继承的另一个好处:多态。

静态语言和动态语言:

静态语言:java就是静态语言,如果参数要传入animal类型,则传入的对象必须是animal或者它的子类对象

动态语言:python,就不一定传入animal类型了,我们只需要传入与animal有相同方法的对象即可

1.4获取对象信息

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

判断对象类型 type()

>>> type(abs)

>>> type(a)

判断是否是基本数据类型,直接写int,str等 >>> type(123)==type(456)

True

>>> type(123)==int

True

>>> type('abc')==type('123')

True

>>> type('abc')==str

True

>>> type('abc')==type(123)

False

判断一个对象是否为函数,可以用types模块定义的常量 >>> 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

使用isinstance

>>> isinstance(d, Dog) and isinstance(d, Animal)

True

并且还可以判断一个变量是否是某些类型中的一种,比如下面的代码就可以判断是否是list或者tuple:

>>> isinstance([1, 2, 3], (list, tuple))

True

>>> isinstance((1, 2, 3), (list, tuple))

True

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

使用dir()

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

['__add__', '__class__',..., '__subclasshook__', 'capitalize', 'casefold',..., 'zfill','upper']

此方法可以查看出类中包含的方法。例如在Python中,如果你调用len()函数试图获取一个对象的长度,实际上,在len()函数内部,它自动去调用该对象的__len__()方法,所以,下面的代码是等价的: >>> len('ABC')

3

>>> 'ABC'.__len__()

3

我们自己写的类,如果也想用len(myObj)的话,就自己写一个__len__()方法: >>> class MyDog(object):

... def __len__(self):

... return 100

...

>>> dog = MyDog()

>>> len(dog)

100

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.x

9

>>> hasattr(obj, 'y') # 有属性'y'吗?

False

>>> setattr(obj, 'y', 19) # 设置一个属性'y'

>>> hasattr(obj, 'y') # 有属性'y'吗?

True

>>> getattr(obj, 'y') # 获取属性'y'

19

>>> obj.y # 获取属性'y'

19

也可以获得对象的方法:

>>> hasattr(obj, 'power') # 有属性'power'吗?

True

>>> getattr(obj, 'power') # 获取属性'power'

>

>>> fn = getattr(obj, 'power') # 获取属性'power'并赋值到变量fn

>>> fn # fn指向obj.power

>

>>> fn() # 调用fn()与调用obj.power()是一样的

81

1.5实例属性和类属性

类属性可以理解为静态属性?

创建实例属性:

实例绑定属性的方法是通过实例变量,或者通过self变量 class Student(object):

def __init__(self, name):

self.name = name

s = Student('Bob')

s.score = 90

创建类属性:

class Student(object):

name = 'Student'

>>> class Student(object):

... name = 'Student'

...

>>> s = Student() # 创建实例s

>>> print(s.name) # 打印name属性,因为实例并没有name属性,所以会继续查找class的name属性

Student

>>> print(Student.name) # 打印类的name属性

Student

>>> s.name = 'Michael' # 给实例绑定name属性

>>> print(s.name) # 由于实例属性优先级比类属性高,因此,它会屏蔽掉类的name属性

Michael

>>> print(Student.name) # 但是类属性并未消失,用Student.name仍然可以访问

Student

>>> del s.name # 如果删除实例的name属性

>>> print(s.name) # 再次调用s.name,由于实例的name属性没有找到,类的name属性就显示出来了

Student

例子:

为了统计学生人数,可以给Student类增加一个类属性,每创建一个实例,该属性自动增加:

class Student(object):

count = 0

def __init__(self, name):

self.name = name

Student.count+=1

标签:__,name,python,self,语法,面向对象,score,Student,属性

来源: https://blog.csdn.net/chen2016/article/details/113617516

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值