今天学了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()#调用方法
结果为:
二、访问控制
类中的属性或方法如果是公共的,则所有实例都可以访问并修改,会带来一定的安全问题。为了防止随笔修改,或者不想被外部变量访问,可以定义为私有属性和方法。
私有变量的定义:以双下划线开始,如__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)
结果为:
调用公共的stuInfo方法:
s = Student('amy',20)
s.stuInfo()
结果:
可见,私有变量不能直接被实例对象访问,若要使用,可通过公共方法。
三、继承
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()
结果为:
此外,Python支持多重继承,即一个子类可以同时继承多个父类,获得多个父类的方法,只要在定义子类时传入多个父类名即可。
如下,表示Dog类继承了Mammal类和Runnable类,可同时获得这两个父类的方法:
classDog(Mammal, Runnable):
Pass
还可以一层层的不断地继承,这样就形成了继承树。在继承树种,子类可获得其上所有父类的方法,如下:
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) #实例属性
结果为:
五、获取对象信息
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()
结果:
2. isinstance()
用于判断一个对象是否属于一个类型。
用于基本类型,如下:
deftest():print(isinstance('abc', str))print(isinstance(123, int))print(isinstance([1,2,3], list))
test()
结果:
用于自定义类和其对象、子类对象和父类的类型判断:
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()
结果:
3. dir()
用于获得一个对象的所有属性和方法,它返回一个包含字符串的list,如下:
__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()
结果: