手把手教你python面向对象编程_自学Python之面向对象编程

今天学了Python中面向对象的知识——类

感觉与Java的很相似但也有不同之处。比如Java中只有静态的属性才能直接用类名访问,非静态属性必须用实例来访问;而Python中,在类中定义的属性是类的属性,直接用类名访问。而__init__初始化的属性是实例的属性。其次Java中的继承和多态是不同的,继承只能单继承,多态可以继承多个类的方法;而Python中继承可以是单继承,只需要在定义子类的时候传入多个父类参数即可。

一、类和对象

1. 类的定义

类名、方法名和属性名的命名:类名首字母大写;方法名和属性名小写,单词之间可用_分割;私有属性以双下划线开头+小写字母,如__age。

定义类时,如果要继承其他类,在类名后的参数中传入要继承的类即可,如Student(object)就表示Student是object的子类,每个类都是object类的子类(关于继承,下面会详细讲解)。

类中方法的第一参数必须是实例变量self,而且调用时不需要传入self,这是与普通方法唯一不同之处。

__init__()方法是在创建实例时调用的,用于对类的实例进行初始化。而该方法的第一个参数必须是self,其他需要绑定的属性在self之后作为参数传入,然后绑定到self,如 self.name = name(self是指实例本身)。

classStudent(object):def __init__(self,name,age):

self.name=name

self.age=agedefstuInfo(self):print("name:"+self.name+",age:"+str(self.age))

2. 对象

类是抽象的,实例是根据类创建的具体对象,创建实例可通过 类名() 的形式,如 Student('amy',20),必须传入与__init__方法匹配的参数,但self不需要传,Python解释器会把实例变量self传进去。

创建实例后就可以通过 object.attribute 的形式调用其属性和方法,如下:

s = Student('amy',20) #创建类的实例

print(s.name) #调用属性

print(s.age)

s.stuInfo()#调用方法

结果为:

938793-20170908105945819-1789027572.png

二、访问控制

类中的属性或方法如果是公共的,则所有实例都可以访问并修改,会带来一定的安全问题。为了防止随笔修改,或者不想被外部变量访问,可以定义为私有属性和方法。

私有变量的定义:以双下划线开始,如__age,定义为私有变量后,调用时会抛出异常,如下:

classStudent(object):def __init__(self,name,age):

self.__name =name

self.__age =agedefstuInfo(self):print("name:"+self.__name+",age:"+str(self.__age))

再次调用:

s = Student('amy',20)print(s.name)

结果为:

938793-20170908110329085-1854012276.png

调用公共的stuInfo方法:

s = Student('amy',20)

s.stuInfo()

结果:

938793-20170908110422897-1535318184.png

可见,私有变量不能直接被实例对象访问,若要使用,可通过公共方法。

三、继承

1. 我的理解

Python中子类继承父类时,直接定义子类的时候,传入父类名即可。

父类:

classAnimal(object):defrun(self):print('Animal is running...')

子类:

class Dog(Animal): #传入父类名作为参数

pass

classCat(Animal):pass

和其他语言一样,子类继承父类后可直接使用父类中的方法。

子类也可以对继承自父类的方法进行修改,此时会覆盖父类的该方法,子类的实例在调用改方法时,执行的是子类的特有功能。

如下,在Cat类中的定义自己的run()方法

classCat(Animal):defrun(self):print('Cat is running...')

两个子类的实例调用run()方法:

dog =Dog()

cat=Cat()

dog.run()

cat.run()

结果为:

938793-20170908111603944-1192758686.png

此外,Python支持多重继承,即一个子类可以同时继承多个父类,获得多个父类的方法,只要在定义子类时传入多个父类名即可。

如下,表示Dog类继承了Mammal类和Runnable类,可同时获得这两个父类的方法:

classDog(Mammal, Runnable):

Pass

还可以一层层的不断地继承,这样就形成了继承树。在继承树种,子类可获得其上所有父类的方法,如下:

938793-20170908132722147-1514855855.png

2. 其他

http://www.cnblogs.com/superxuezhazha/p/5737955.html 在学习的过程中,看到了这边博客,觉得博主写的挺不错的,在此转载一下。

四、类属性和实例属性

1. 概念

类属性即在类中定义、属于类的属性,实例属性则是属于类的实例的属性,是在创建类的实例时绑定的属性。

类属性可以通过类直接访问,也可以通过类的属性访问;而实例属性只能通过类的实例访问。

在一个类中,如果类属性和实例属性同名,通过实例访问时,获取到的是实例属性的值,就是说实例属性覆盖了类属性;而直接通过类名获得的一定是类属性的值。

2. 举例

classStudent(object):

name= 'class'

def __init__(self, name):

self.name=name

s= Student('obj')print(Student.name) #类属性

print(s.name) #实例属性

结果为:

938793-20170908134050913-1652169706.png

五、获取对象信息

1. type()

用于返回对象类型,特定情况下可通过判断类型是否与期望一致,再继续后续操作。

可用于基本数据类型、引用类型和自定义类型等,具体如下:

importmathimporttypesimportsysclassStudent():pass

deffn():pass

deftest():print(type(123))print(type('str'))print(type(12.34))print(type(None))print(type([1,2,3]))print(type((123,456)))print(type({'key':'value'}))print(type(math))print(type(Student))print(type(fn))print(type(abs))print(type(123) == type(456))print(type('abc') ==str)print(type(fn) ==types.FunctionType)print(type(abs)==types.BuiltinFunctionType)print(type(lambda x: x)==types.LambdaType)

test()

结果:

938793-20170908140025194-1738489.png

2. isinstance()

用于判断一个对象是否属于一个类型。

用于基本类型,如下:

deftest():print(isinstance('abc', str))print(isinstance(123, int))print(isinstance([1,2,3], list))

test()

结果:

938793-20170908140343866-1468167.png

用于自定义类和其对象、子类对象和父类的类型判断:

classAnimal(object):defrun(self):print('Animal is running...')classDog(Animal):pass

classCat(Animal):pass

deftest():

dog=Dog()

cat=Cat()print(isinstance(dog,Dog))print(isinstance(cat,Cat))print(isinstance(dog,Animal))print(isinstance(cat,Animal))

test()

结果:

938793-20170908140852335-689553287.png

3. dir()

用于获得一个对象的所有属性和方法,它返回一个包含字符串的list,如下:

938793-20170908141115226-1706972064.png

__xxx__的属性和方法是有特殊用途的,其余表都是普通方法。比如__len__方法返回长度。在Python中,如果调用len()函数获取一个对象的长度,实际上,在len()函数内部,会自动去调用该对象的__len__()方法,即:

len('abc') 等价于 'abc'.__len__()。

此外,hasattr()、getattr()和setattr() 可用来操作对象上的属性

classStudent(object):def __init__(self,name,age):

self.name=name

self.age=agedefstuInfo(self):print("name:"+self.name+",age:"+str(self.age))deftest():

s= Student('Amy',20)print(hasattr(s,'name')) #判断对象s是否有name属性

print(hasattr(s,'age'))print(hasattr(s,'gender'))print(getattr(s,'name')) #获得对象s的name属性值

print(getattr(s,'age'))print(getattr(s,'gender','404')) #获得对象s的gender属性值,不存在时返回404

setattr(s,'name','Bob') #设置对象s的name属性值

print(s.name)

setattr(s,'age',22)print(s.age)

setattr(s,'gender','femal')print(s.gender)

test()

结果:

938793-20170908143106647-1566136932.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值