Python学习目录java
面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想。OOP把对象做为程序的基本单元,一个对象包含了数据和操做数据的函数。python
class Student(object):
pass
stone = Student()
stone.name = "stone"
stone.age = 2
print(stone.name, stone.age)
复制代码
上面代码中:编程
class Student(object):
def __init__(self, name, age):
self.name = name
self.age = age
def print_info(self):
print(self.name, self.age)
stone = Student("stone", 18)
stone.print_info()
复制代码
上面代码中:api
__init__
方法的第一个参数永远是self
,表示建立的实例自己,所以,在__init__
方法内部,就能够把各类属性绑定到self
,由于self
就指向建立的实例自己。相似于java的构造函数。self
外,其余和普通函数同样。要调用一个方法,只须要在实例变量上直接调用,除了self
不用传递,其余参数正常传入。__
开头,就变成了一个私有变量(private),只有内部能够访问,外部不能访问。__xxx__
的,也就是以双下划线开头,而且以双下划线结尾的,是特殊变量,特殊变量是能够直接访问的,不是private变量。在OOP程序设计中,当咱们定义一个class的时候,能够从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)。和java同样。网络
静态语言 vs 动态语言:ssh
对于静态语言(例如Java)来讲,若是须要传入Animal
类型,则传入的对象必须是Animal
类型或者它的子类,不然,将没法调用Animal
中的方法。对于Python这样的动态语言来讲,则不必定须要传入Animal
类型。咱们只须要保证传入的对象有Animal
中的方法就能够了。函数式编程
>>> 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
复制代码
以上代码能够看出,判断基本数据类型能够直接写
int
,str
等,但若是要判断一个对象是不是函数怎么办?能够使用types
模块中定义的常量。函数
>>> isinstance([1, 2, 3], (list, tuple))
True
>>> isinstance((1, 2, 3), (list, tuple))
Tru
复制代码
能够判断一个变量是不是某些类型中的一种,好比上面的代码就能够判断是不是list或者tuplepost
若是要得到一个对象的全部属性和方法,能够使用dir()
函数,它返回一个包含字符串的list,好比,得到一个str对象的全部属性和方法:学习
>>> dir('ABC')
['__add__', '__class__',..., '__subclasshook__', 'capitalize', 'casefold',..., 'zfill']
复制代码
相似__xxx__
的属性和方法在Python中都是有特殊用途的,好比__len__
方法返回长度。在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'
<bound method MyObject.power of <__main__.MyObject object at 0x10077a6a0>>
>>> fn = getattr(obj, 'power') # 获取属性'power'并赋值到变量fn
>>> fn # fn指向obj.power
<bound method MyObject.power of <__main__.MyObject object at 0x10077a6a0>>
>>> fn() # 调用fn()与调用obj.power()是同样的
81
复制代码
类自己须要绑定一个属性:
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
复制代码