面向对象编程
在python中,通过class,可以定义一个类,类名开头一般是大写字母开头,比如 class Animal,也可以写成 class Animal(): 或者 class Animal(object):
定义了类之后就可以对类进行实例化:使用一个名称来接收变量
class Animal(): pass dog = Animal()
实例可以给属性赋值,比如:
xiaohong.name = 'xiaohong'
xiaohong.sex = 'girl'
xiaohong.age = 13
print(xiaohong.name)
print(xiaohong.sex)
print(xiaohong.age)
除此以外,这些属性也可以和普通变量一样进行运算。比如xiaohong长大了一岁:
xiaohong.age = xiaohong.age + 1
为了统一属性的名称,一般会在类初始化一个方法,来添加信息属性,初始化实例时,会自动调用__init__方法:
class Person(object):
def __init__(self, name, sex, age):
self.name = name
self.sex = sex
self.age = age
__init__() 方法的第一个参数必须是 self,定义类后,就可以相应的实例化对象了,需要注意的是,在实例化的时候,需要提供除self以外的所有参数。
xiaohong = Person('Xiao Hong', 'girl', 14)
print(xiaohong.name)
print(xiaohong.sex)
print(xiaohong.age)
# 但当访问不存在的属性时,依然会报错
print(xiaohong.birth)
实例对象绑定的属性只属于这个实例,而不会影响其他实例的属性。同样的,类也可以绑定实例:
class Animal(object):
localtion = 'Asia'
def __init__(self, name, age):
self.name = name
self.age = age
dog = Animal('wangwang', 1)
print(dog.localtion) # ==> Asia
类属性也可以添加和修改,当修改后,其他实例访问这个属性也会变更。
Animal.localtion = 'Africa'
print(cat.localtion) # ==>Africa
属性可以分为类属性和实例属性,当一个属性同时出现时,优先选择类属性。
class Animal(object):
localtion = 'Asia'
def __init__(self, name, age, localtion):
self.name = name
self.age = age
self.localtion = localtion
dog = Animal('wangwang', 1, 'GuangDong')
cat = Animal('mimi', 3, 'ChongQing')
print(dog.localtion) # ==> GuangDong
print(cat.localtion) # ==> ChongQing
print(Animal.localtion) # ==> Asia
当不同名的时候,实例可以调用类的属性,但是实例不可以修改类的属性,只是给实例新增绑定了一个属性:
class Animal(object):
localtion = 'Asia'
def __init__(self, name, age):
self.name = name
self.age = age
cat = Animal('mimi', 3)
print(cat.localtion) # ==> Asia
#通过实例修改类的属性
cat.localtion = 'Africa'
print(Animal.localtion) # ==> Asia #未修改成功
私有属性是双下划线‘_’ 开头的属性,私有属性不会被外部调用。
# 类私有属性
class Animal(object):
__localtion = 'Asia'
print(Animal.__localtion)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object 'Animal' has no attribute '__localtion'
# 实例私有属性
class Animal(object):
def __init__(self, name, age, localtion):
self.name = name
self.age = age
self.__localtion = localtion
dog = Animal('wangwang', 1, 'GuangDong')
print(dog.name) # ==> wangwang
print(dog.age) # ==> 1
print(dog.__localtion)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Animal' object has no attribute '__localtion'
实例怎么调用私有属性:
class Animal():
def __init__(self,name):
self.name = name
def get_name(self):
return self._name
a = Animal('huahua')
print(a.get_name()) ===>huahua
类调用私有属性,使用classmethod 来标记为类方法,类方法的第一个参数将传入类本身,通常记为cls,cls._localtion 相当于 Animal._location:
class Animal(object):
__localtion = 'Asia'
def __init__(self, name, age):
self.name = name
self.age = age
@classmethod
def set_localtion(cls, localtion):
cls.__localtion = localtion
@classmethod
def get_localtion(cls):
return cls.__localtion
print(Animal.get_localtion()) # ==> Asia
Animal.set_localtion('Afica')
print(Animal.get_localtion()) # ==> Africa
python类的继承
当一个类继承另一个类时,就会自动拥有这个类的属性。继承某个类时,需要在括号内写明继承类的名称,在__init__中,需要调用super来初始化从父类调用过来的属性。
class Person(object):
def __init__(self, name, gender):
self.name = name
self.gender = gender
#继承Person类
class Student(Person):
def __init__(self, name, gender, score):
super(Student, self).__init__(name, gender)
self.score = score
student = Student('Alice', 'girl', 100)
print(student.name) # ==> Alice
print(student.gender) # ==> girl
print(student.score) # ==> 100
使用isinstances来判断某一个变量是什么类型的:
class Person(object):
def __init__(self, name, gender):
self.name = name
self.gender = gender
class Student(Person):
def __init__(self, name, gender, score):
super(Student, self).__init__(name, gender)
self.score = score
class Teacher(Person):
def __init__(self, name, gender, course):
super(Teacher, self).__init__(name, gender)
self.course = course
p = Person('Tim', 'Male')
s = Student('Bob', 'Male', 88)
t = Teacher('Alice', 'Female', 'English')
>>> isinstance(p, Person)
True # p是Person类型
>>> isinstance(p, Student)
False # p不是Student类型
>>> isinstance(p, Teacher)
False # p不是Teacher类型
>>> isinstance(s, Person)
True # s是Person类型
>>> isinstance(s, Student)
True # s是Student类型
>>> isinstance(s, Teacher)
False # s不是Teacher类型
在继承链上,父类的实例不能是子类类型,因为子类属性比父类多了一些。子类 的实例可以看成他本身的类型,也可以看成父类的类型。
isinstance 也可以用于python自有类型的判断。
s = 'this is a string.'
n = 10
isinstance(s, int) # ==> False
isinstance(n, str) # ==> False
python中,一个类被多个类继承时,都拥有某一个方法,但是返回的结果不同,在继承时,可以重新定义方法的内容。这种方法被称为多态。在实际调用时,会优先查找自身,自身不存在时再查找父类的这个类。
class Person(object):
def __init__(self, name, gender):
self.name = name
self.gender = gender
def who(self):
return 'I am a Person, my name is %s' % self.name
class Student(Person):
def __init__(self, name, gender, score):
super(Student, self).__init__(name, gender)
self.score = score
def who(self):
return 'I am a Student, my name is %s' % self.name
p = Person('Tim', 'Male')
s = Student('Bob', 'Male', 88)
I am a Person, my name is Tim
I am a Student, my name is Bob
python允许多个父类继承,称之为多类继承。多类继承和蛋类继承写法相同,就是括号中写多个类名,使用逗号隔开。
class A(object):
def __init__(self, a):
print ('init A...')
self.a = a
class B(A):
def __init__(self, a):
super(B, self).__init__(a)
print ('init B...')
class C(A):
def __init__(self, a):
super(C, self).__init__(a)
print ('init C...')
class D(B, C):
def __init__(self, a):
super(D, self).__init__(a)
print ('init D...')
A类的__init__被继承两次,但是调用时只会掉用一次。结果如下:
>>> d = D('d') init A... init C... init B... init D...
python类的特殊方法
python的某些内置对象,str()方法可以把这些对象转换成字符串方法。str()f方法返回的结果其实是对象的内建方法__str__返回的。
num = 12
str(num) # ==> '12'
d = {1: 1, 2: 2}
str(d) # ==> '{1: 1, 2: 2}'
l = [1,2,3,4,5]
str(l) # ==> '[1, 2, 3, 4, 5]'
python类的__len__方法。通过内建方法len(),可以得出列表或者元组中元素的个数。
class Class:
def __init__(self, students):
self.students = students
def __len__(self):
return len(self.students)
students = ['Alice', 'Bob', 'Candy']
class_ = Class(students)
len(class_) # ==> 3
python类的__slots__方法,由于python是动态语言,任何实例在运行时都可以添加属性。
class Student(object):
def __init__(self, name, gender, score):
self.name = name
self.gender = gender
self.score = score
student = Student('Bob', 'Male', 99)
student.age = 12 # ==> 动态添加年龄age属性
如果想要限制属性的添加,可以使用__slots__方法,此时再添加age属性就会报错。
class Student(object):
__slots__ = ('name', 'gender', 'score')
def __init__(self, name, gender, score):
self.name = name
self.gender = gender
self.score = score
如果把一个类实例也变成一个 可调用对象,可以实现一个特殊的方法__call__()
class Person(object):
def __init__(self, name, gender):
self.name = name
self.gender = gender
def __call__(self, friend):
print('My name is {}...'.format(self.name))
print('My friend is {}...'.format(friend))
>>> p = Person('Bob', 'Male')
>>> p('Alice') # ==> 用函数的方式调用Person类的实例p
My name is Bob...
My friend is Alice...
python的模块
python本身具有很多模块,当自定义模块时,如果我们想要创建一个tools模块,用来实现众多的工具函数,那么我们可以创建一个tools.py文件。
# tools.py
def say_hello():
print('hello')
def say_goodbye():
print('goodbye')
导入这个文件,import tools ,需要注意路径。在tools.py下新建一个文件,就可以直接调用。
# main.py
import tools # 导入模块
tools.say_hello() # 调用模块里面的say_hello()函数
tools.say_goodbye() # 调用模块里面的say_goodbye()函数