Python面向对象(基础)
面向对象
Python是支持面向对象的,面向对象编程是一种程序设计思想。
类和实例(基础)
面向对象最重要的就是类(class)和实例(instance),实例是对类的实现。而类是指对某一个对象所共有的特点抽象出来封装组合在一起。
定义类
在Python中定义类很简单,使用关键字class定义,像是这样定义一个人类的类:
class Human(object):
pass
class后面紧接着是类名,即Human,类名通常是大写开头的单词,紧接着是(object),表示该类是从哪个类继承下来的,继承的概念我们后面再讲,通常,如果没有合适的继承类,就使用object类,这是所有类最终都会继承的类。
就像是上面讲到的,实例是对类的实现,类的实现也很简单:
man = Human()
print(man)
print(type(man))
通过类名+()就可以,
<__main__.Human object at 0x000001AB6196B470> <class '__main__.Human'>
你可以看到是一个‘Human object’,类型是一个class。当然我们的class里面还是很简单的,我们亦可以给他加上一些东西:比如一些属性、和各种方法,我们需要用到一个重要的方法:
class Human(object):
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
def pri(self):
print(self.name, self.age, self.sex)
init方法是进行初始化用的,他的第一个参数永远是self,self是自己的意思,通过这个参数,你可以将后面这些传入的参数绑定到自己的创建的实例中去。当你定义了init方法的时候,你在创建实例的时候就必须传入相应的参数了,同时你创建的实例也可以调用类里面的方法,就像是这样:
man = Human("yznx", "19", "男")
man.pri()
print(man.name, man.age, man.sex)
------
yznx 19 男
yznx 19 男
同时你也可以通过“.”来访问实例的属性,获得的结果是一样的。这就是类的基本知识,同时你想要对类里面的方法进行扩展也是很方面的。
私有属性和方法
在上面的基础中,我们了解到可以通过“.”来查看实例的属性,但是如果你想要某些属性只能够在类的内部才能够使用而外部不能使用又该怎么办呢?你可以使用私有属性和私有方法来实现。私有属性和私有办法定义方法很简单,通过__(两个下划线)来定义,当你使用两个下划线来定义过后,这个属性和方法就这能在类里调用。还是拿上面的例子继续做示范:
class Human(object):
def __init__(self, name, age, sex):
self.name = name
self.__age = age
self.sex = sex
def pri(self):
print(self.name, self.age, self.sex)
def __priage(self):
print(self.__age)
man = Human("yznx", "19", "男")
man.pri()
print(man.name, man.age, man.sex)
man.priage()
我们把年龄设置为了私有变量,男孩子还好,女孩子们始终都是18岁呢。我们来看一下结果:
yznx 19 男
File "E:/python_project/flask01/test/test.py", line 15, in <module>
print(man.name, man.__age, man.sex)
AttributeError: 'Human' object has no attribute '__age'
你会发现报错了,在类的外部我们是不能访问到__age这个变量,同样我们也不能访问到私有方法。如果想要获取到这个参数怎么办呢?如果我还想要修改这个变量怎么办呢? 这里呢就讲到面向对象编程里面很重要的两个方法了,那就是get()and set()方法了。就像是这样:
def get_age(self):
return self.__age
def set_age(self, new_age):
self.__age = new_age
这样做好麻烦啊,这样有什么好处呢?没好处我可不干。这样保证了外部代码不能随意修改对象内部的状态,这样通过访问限制的保护,代码更加健壮。同时还可以在类的内部进行对传入的参数进行验证,避免无效参数的传入。
继承和多态
在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)。我们继续用上面的例子:
class Boy(Human):
pass
boy = Boy("oko", "15", "当然是男孩子啊")
boy.pri()
------
oko 15 当然是男孩子啊
15
你可以看到,我们在Boy类里面什么都没写,为什么还是可以使用配pri()方法呢?因为Boy是继承了Human,所以Human有的东西他都有。继承最大的好处是子类获得了父类的全部功能。
当然如果你对父类里面的功能不是很满意,他不可以满足你所有的需求还可以自己在子类里写自己的方法。同时你如果觉得父类里面有些方法不符合你需要,像是上面那个,你都已经说是Boy了,再问性格岂不是做无用之功。所以我们可以来重写一下父类的pri方法:
class Boy(Human):
def pri(self):
print(self.name, self.age, "我喜欢好看的小姐姐")
boy = Boy("oko", "15", "你猜我喜欢的是谁?")
boy.pri()
------
oko 15 我喜欢好看的小姐姐
注意:子类也不能访问父类的私有变量
获取对象信息
说一个不怎么常见的方法:dir()方法,这个方法会以列表的形式放回一个对象的所有方法和属性,对于类来说就包括你自己定义和内置方法:
print(dir(man))
还是上面的例子中创建的对象,看一下结果:
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'name', 'pri', 'sex']