类和实例
python类语法和java有点类似,__init__
作为自动初始化方法,第一个self参数代表了java中的this,创建对象的时候不需要new关键字。
>>> class Student(object):
... def __init__(self,name,age):
... self.name=name
... self.age=age
...
>>> stu=Student('lisong',18)
>>> stu.name
'lisong'
>>> sut.age
18
访问限制
在python中,以双下划线__
开头的变量属于私有变量,外部访问不了,变量名类似__xxx__
的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private
变量,所以,不能用__name__
、__score__
这样的变量名。
>>> class Student(object):
... def __init__(self,name,age):
... self.__name=name
... self.__age=age
...
>>> stu=Student('lisong',18)
>>> stu.__name
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute '__name'
>>>
虽然看起来,私有变量在外部访问不了,但其实这是个假象,python解释器只是把这些双下划线开头的私有变量改了标识,比如__name
被改成了_Student__name
。
>>> stu._Student__name
'lisong'
>>>
虽然这样我们就可以访问到私有变量了,但强烈建议不要这么写代码,因为不同的python解释器可能会按不同的规则来改写私有变量。
继承和多态
继承
>>> class Animal:
... def run(self): #self不能省略
... print('animal is running')
...
>>> class Dog(Animal):
... pass
...
>>> class Cat(Animal):
... def run(): #可覆盖父类方法
... print('cat is running')
...
>>> ani=Animal()
>>> ani.run()
>>> ani=Animal()
>>> ani.run()
animal is running
>>> dog=Dog()
>>> dog.run()
animal is running
>>> cat=Cat()
>>> cat.run()
cat is running
多态
>>> class Animal:
... def run(self):
... print('animal is running')
...
>>> class Dog(Animal):
... def run(self):
... print('dog is running')
...
>>> class Cat(Animal):
... def run(self):
... print('cat is running')
...
>>> def run_twice(animal):
... animal.run()
...
>>> run_twice(Animal())
animal is running
>>>
>>> run_twice(Dog())
dog is running
>>>
>>> run_twice(Cat())
cat is running
>>> isinstance(Animal(),Animal)
True
>>> isinstance(Dog(),Animal)
True
>>> isinstance(Dog(),Dog)
True
>>>
python中的多态与java的多态是有一些区别的,java属于静态语言,定义run_twice时,会去检查其参数类型,不是Animal时会编译(编译成字节码)不通过,而对于python来说,参数类型可以任何类型,运行时才知道具体的类型,只要类型有run方法就能正确运行,这里的特性和js类似。
多态的意义在于,我们可以定义一种操作,这种操作需要某一种类型的数据就能正确执行,而不需要管数据具体的类型时哪一种类型,只要其父类是操作需要的类型就行了。
类型判断
python类型判断有两个方法,一个type方法,一个是isinstance方法,type返回一个类型,isinstance接受两个参数,两个函数的功能基本一样,不过isinstance还可以判断继承类。
class Animal:
def run(self):
print('animal is running')
class Dog(Animal):
def run(self):
print('animal is running')
print(type(123)==int) #True
print(type('abc')==str) #True
print(type(True)==bool) #True
print(type(Dog())==Dog) #True
print(type(Dog())==Animal) #False
print(isinstance(123,int)) #True
print(isinstance('abc',str)) #True
print(isinstance(True,bool)) #True
print(isinstance(Dog(),Dog)) #True
print(isinstance(Dog(),Animal)) #True
def fn():
pass
import types #如果要判断是否为函数,需要引入types
print(type(fn)==types.FunctionType) #True
print(isinstance(fn,types.FunctionType)) #True
静态属性
可以给类添加静态属性,通过对象和类都可以访问静态属性
class Animal:
name='kitty'
print(Animal.name) #kitty
print(Animal().name) #kitty