写在前面
众所周知,python是门面向对象编程语言,面向对象是一个程序设计和编程思想,即一切皆为对象。
面向对象
面向对象三要素:封装,继承, 多态
- 封装?
把一致的行为或者公共的部分封装成一个类或者方法。
比如把一定重量的面粉装到袋子里保存起来就是封装的过程。 - 继承?
通过继承来实现父类的特性,子类继承父类。
比如我们都是从父母那里继承到了一些特定的行为 - 多态?
多态顾名思义就是多种形态,通过多态来实现基于对象类型的动态分布。
举个栗子:我们都是从我们父辈那里继承了一些特定的行为,但是我们又不是完全的继承复制,我们也有我们自己的思想和特定行为。这个就是多态的表现 - 看图理解
声明:以下图片来源于网络,不代表作者态度和观点,侵权删!!!
面向对象进阶
- 定义类,创建对象
定义类的时候使用关键字: class 来表示,类后面是类名,通过使用驼峰命令法来指定。
object: 是所有类的基类,如果在定义类的时候不写(object),默认是继承object的
__ init __:初始化方法,用来给类定义参数
self : 表示类对象本身,可以在类的内部访问类属性和类对象
c = Person(name=‘jack’, age=18) 来创建类对象
c.walk() 通过类对象来实现对类中的方法的访问
class Person(object):
def __init__(self, name, age):
self._name = name
self._age = age
def walk(self):
print("I am {} i can run".format(self._name))
return
if __name__ == '__main__':
c = Person(name='jack', age=18)
c.walk()
- 访问权限设置
python中并没有像JAVA中那样明显的访问权限(public,private, protected, default)。
python只有公开和私有的两种权限,大部分情况下都建议使用公开的权限
通过对函数名前面添加双下划线的方式来定义对象的私有化 eg: def __run(self): pass
class Person(object):
def __init__(self, name, age, family):
self._name = name
self._age = age
self.__family = family
def walk(self):
print("I am {} i can run".format(self._name))
return
def __run(self):
print(self.__family)
print("This is private function")
return
if __name__ == '__main__':
c = Person(name='jack', age=18, family="python")
c.walk()
print(c._name, c.__foo) # AttributeError: 'Person' object has no attribute '__foo'
c.__run() # AttributeError: 'Person' object has no attribute '__run'
- @property装饰器
python中对属性访问保护一般在命名的时候使用单下划线开头,这样在设置类属性的时候是不安全的,不能保证设置的类属性满足要求。
通过property来对类属性进行了预检查,保证了程序的正确
class Person(object):
def __init__(self, name, age, family):
self._name = name
self._age = age
self.__family = family
@property
def age(self):
return self._age
@age.setter
def age(self, value):
if not isinstance(value, int):
raise ValueError("age must be int structure")
if value < 0 or value > 100:
raise ValueError('age must between 0 ~ 100!')
self._age = value
@property
def name(self):
return self._name
if __name__ == '__main__':
c = Person(name='jack', age=18, family="python")
c.age = 9999 # ValueError: age must between 0 ~ 100!
c.name = 'lisa' # AttributeError: can't set attribute
- __slots __ 魔法方法
Python是一门动态语言。通常,动态语言允许我们在程序运行时给对象绑定新的属性或方法,当然也可以对已经绑定的属性和方法进行解绑定。但是如果我们需要限定自定义类型的对象只能绑定某些属性,可以通过在类中定义__slots__变量来进行限定。需要注意的是__slots__的限定只对当前类的对象生效,对子类并不起任何作用。
class Person(object):
__slots__ = ('_name', '_age', '_family', '_gender')
def __init__(self, name, age):
self._name = name
self._age = age
@property
def age(self):
return self._age
@age.setter
def age(self, value):
if not isinstance(value, int):
raise ValueError("age must be int structure")
if value < 0 or value > 100:
raise ValueError('age must between 0 ~ 100!')
self._age = value
@property
def name(self):
return self._name
if __name__ == '__main__':
c = Person(name='jack', age=18)
c._family = 'python'
c._sss = 'ssss' # AttributeError: 'Person' object has no attribute '_sss'
- 静态方法和类方法
类方法classmethod:可以由类名直接调用,将类本身作为对象操作的方法,且第一个参数必须是当 前类对象,通过它来传递类的属性和方法(不能传实例的属性和方法)
静态方法:只是存在于类方法中,没有self和cls参数,不能使用类或实例的任何属性和方法
__author__ = 'jack@csdn.com'
class Person(object):
def __init__(self, name, age):
self._name = name
self._age = age
@staticmethod
def is_valid(name, age):
if not isinstance(name, str):
raise ValueError("name must be strig")
if not isinstance(age, int):
raise ValueError("age must be integer")
@classmethod
def now(cls):
return cls(__author__, len(__author__))
@property
def age(self):
return self._age
@age.setter
def age(self, value):
if not isinstance(value, int):
raise ValueError("age must be int structure")
if value < 0 or value > 100:
raise ValueError('age must between 0 ~ 100!')
self._age = value
@property
def name(self):
return self._name
if __name__ == '__main__':
c = Person(name='jack', age=18)
# c.is_valid(name='jack', age='17') # ValueError: age must be integer
cc = c.now()
print(cc.name, cc.age) # classmethod可以返回获得和类相关的信息并且可以创建出类的对象