stay hungry stay foolish

python(面向对象)

类和实例

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