您的位置:首页 > 编程语言 > Python开发

python 面向对象

2019-10-24 21:35 1121 查看

面向对象

对象:是指现实中的物体实体化,对象有很过属性(名字、年龄..),也有很多行为(学习、吃饭..),实例即对象。对象同时也是通过类定义的数据结构实例,对象包括两个数据成员(类变量和实例变量)和方法。对象可以包含任意数量和类型的数据。

实例化:创建一个类的实例,类的具体对象化,实例就是类的实例化,d1 = gog(),d1即为实例

:拥有相同属性和方法(行为)的对象划为一组,称为类,类是创建对象的工具

方法:类中定义的函数

类变量:在类中被定义的变量,通常以self.variable的形式被定义,类变量通常不作为实例变量使用

方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行修改,这个过程叫方法的覆盖,也叫方法的重写

继承:及一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。

Python中的类提供了面向对象编程的所有基本功能:类的继承机制允许多个基类,派生类可以覆盖基类中的任何方法,方法中可以调用基类中的同名方法。

类定义  语法格式

  class 类名(继承列表):

    """类的文档字符串"""

    类变量的定义

    实例方法的定义

    类方法的定义(@classmethod)

    静态方法的定义(@staticmethod)

作用:

  创建一个类,类用于描述对象的行为和属性,类用于创建此类的一个或者多个对象(实例)类名实质上是变量,它绑定一个类

类的文档字符串

类内第一个没有赋值给任何变量的字符串为类的文档字符串,类的文档字符串可以用类的 __doc__属性访问

help(Dog)    查看文档字符串

类.__doc__属性用来绑定文档字符串

类变量的定义

类变量就类的属性,此属性属于类,不属于此类的实例

作用:通常用来存储该类创建的对象的共有属性

说明:类变量可以通过该类或该类的实例直接访问;类变量可以通过此类的实例对象的__class__属性间接访问

class Human:
total_count = 0  # 类变量

def __init__(self, name):
print(name, '对象被创建')

print(Human.total_count)  # 类直接访问类变量 0
h1 = Human('小张')
print(h1.total_count)  # 0 用此类的实例可以访问类变量
h1.total_count = 100  # 为对象添加实例变量
print(h1.total_count)  # 100, 优先访问对象的实例变量
print(Human.total_count)  # 0, 访问类的类变量
print(h1.__class__.total_count)  # 0 通过此类的实例对象的__class__属性来访问类变量

初始化方法 __init__()

1、初始化方法__init__()会在构造函数创建实例后自动调用

2、初始化方法如果需要return语句返回,则只能返回None

3、一般类都会倾向于将(实例)对象创建为有初始化状态的

4、实例方法至少有一个形参,第一个形参代表调用这个方法的实例,一般命名为'self',因此类可能会定义一个名为__init__()的特殊方法(构造方法)

5、__init__有形参时,参数会通过__init__()传递到实例化对象上。

class complex:
# 构造函数,在实例化时做一些类的初始化工作,__init__用来传参的
def __init__(self, name, age):  # 定义类的方法
self.name = name    # 实例变量(静态属性)
self.age = age

x = complex("作者",23)       # 类的实例化,变成具体对象
print(x.name,x.age)

# 作者 23

类的方法与普通的函数只有一个特殊的区别————他们必须有一个额外的第一参数名称self,按照惯例它的名称是self,谁调用这个类的方法,self就指向谁。self代表类的实例化,而非类

class Test:             #定义一个名为Test的类
def prt(self):      #定义类的方法prt
print(self)
print(self.__class__)   # self.__class__指向类

t = Test()  #类的实例化
t.prt()     #访问类的方法

# <__main__.Test object at 0x000001836DFE10B8>
# <class '__main__.Test'>

self代表的是类的实例,代表当前对象的地址,而self.__class__则指向类名。

self不是python的关键词,我们把self换成其他的表示符也是可以的(在这里我们把self换成runoob)

class Test:  # 定义一个名为Test的类
def prt(runoob):  # 定义类的方法prt
print(runoob)
print(runoob.__class__)

t = Test()  # 类的实例化
t.prt()  # 访问类的方法
# <__main__.Test object at 0x000001836DFE10B8>
# <class '__main__.Test'>

类的__slots__列表

作用:限定一个类创建的实例只能有固定属性(实例属性),不允许对象添加列表以外的属性(实例变量)

说明:__slots__列表绑定一个字符串列表,含有__slots__列表的类所创建的实例对象没有__dict__属性,即此实例不用字典来存储对象的属性(实例变量)

__slots__ = [" ", " "]

class Human:
# 以下列表限制此类的对象只能有'name' 和'age' 属性
__slots__ = ['name', 'age']

def __init__(self, name, age):
self.name, self.age = name, age

h1 = Human("Tarena", 15)
print(h1.age)  # 15
# h1.Age = 18  # 出错,h1对象没有Age属性,也不允许有Age属性
print(h1.age)  # 15

类方法 @classmethod

类方法是用于描述类的行为的方法,类方法属于类,不属于类的实例

说明:类方法需要使用@classmethod装饰器定义,

  def关键词来定义一个方法,类方法至少有一个形参,第一个参数用于绑定类,约定写为" cls ",类和该类的实例都可以调用类的方法

class people:  # 定义一个类
# 定义类的属性
name = ''
age = 0
# 定义私有属性,私有属性在类外部无法直接进行访问
_weight = 0

# 定义构造的方法
def __init__(self, n, a, w):
# 定义类的初始化属性
self.name = n
self.age = a
self._weight = w

# 定义类的方法
@classmethod
def speak(cls):
print("%s说:我%d岁" % (self.name, self.age))

# 实例化类  把一个类变成具体对象叫做类的实例化
p = people("作者", 18, 30)
p.speak()       # 作者说:我18岁

静态方法  @staticmethod

静态方法是定义在类内部的函数,此函数的作用域是类的内部

说明:静态方法需要使用 @staticmethod装饰器定义,

  静态方法与普通函数定义相同,不需要传入self实例参数和cls参数,静态方法只能凭借该类或类创建的实例调用,静态方法不能访问类变量和实例变量(属性)

class A:
@staticmethod
def myadd(a, b):
return a + b

print(A.myadd(100, 200))  # 300
a = A()  # 创建实例
print(a.myadd(300, 400))  # 700

实例方法、类方法、静态方法、函数小结

  不想访问类内和实例内的变量,用静态方法

  只想访问类内变量,不想访问实例变量,用类方法

  即要访问内变量,也想访问实例变量用实例方法

  函数与静态方法相同,只是静态方式的作用域定义在类内

class Classname:
@staticmethod
def fun():
print('静态方法')

@classmethod
def a(cls):
print('类方法')

# 普通方法
def b(self):
print('普通方法')

Classname.fun()     # 静态方法
Classname.a()       # 类方法

C = Classname()
C.fun()             # 类方法
C.a()               # 类方法
C.b()               # 普通方法

类的实例化

类实例化后,可以使用其属性,实际上,创建一个类之后,可以通过类名访问其属性

d1 = dog() # 调用构造函数创建实例化对象

类对象  

类对象支持两种操作:属性引用和实例化。

类对象创建后,类命名空间中的所有命名都是有效属性名,类定义如下所示:

class Myclass:  # 定义一个自己的类
"""一个简单的类实例"""
i = 12345  # 类变量

def f(self):  # 定义类的方法
return "你好呀"

# 类的实例化,用x来绑定以便后面使用,不然用完之后就释放了
x = Myclass()  # 把一个类变成具体对象的过程叫做实例化(初始化)
# 访问类的属性和方法
print("Myclass类的属性i:", x.i)     # 12345
print("Myclass类的方法f:", x.f())   # 你好呀!

 python支持 在类的外面 创建类的属性

class Dog:
def eat(self, food):
# print("小狗正在吃:", food)
print(self.color, '的', self.kinds, '正在吃', food)

dog1 = Dog()    # 类的实例化
dog1.kinds = '京巴'  # 为dog1对象添加kinds属性,绑定为'京巴'
dog1.color = '白色'  # dog1添加属性 为'白色'
dog1.color = '黄色'  # 改变dog1的color属性

# 访问dog1 的属性
print(dog1.color, "的", dog1.kinds)  # 黄色 的 京巴

dog2 = Dog()
dog2.kinds = '哈士奇'
dog2.color = '黑白相间'
print(dog2.color, '的', dog2.kinds)  # 黑白相间 的 哈士奇

dog1.eat('骨头')  # 黄色 的 京巴 正在吃 骨头
dog2.eat('窝头')  # 黑白相间 的 哈士奇 正在吃 窝头

# 定义私有属性,私有属性在类外部无法直接进行访问 __weight = 0,在变量前面加双下划线

删除属性del语句

  del 变量名  删除变量

  del 列表[整数表达式]  删除列表中的元素

  del 字典[键]        删除字典中的键

  del 对象.属性       删除对象的属性

析构方法:

  class 类名:

    def __del__(self):

      ......

说明:析构方法在对象被销毁时做任何事情,因为销毁的时间难以确定

预置实例属性:

  __dict__属性

  __dict__属性绑定一个存储此实例自身变量的字典

class Dog:
pass

dog1 = Dog()
print(dog1.__dict__)  # {}
dog1.kinds = '京巴'
print(dog1.__dict__)  # {'kinds': '京巴'}

__class__属性:

  此属性用于绑定创建此实例的类

 作用:可以借助于此属性来访问创建此实例的类

class Dog:
pass

dog1 = Dog()
print(dog1.__class__)  # <class '__main__.Dog'>
dog2 = dog1.__class__()
print(dog2.__class__)  # <class '__main__.Dog'>

用于类的函数:

  isinstance(obj, class_or_tuple) 返回这个对象obj是否是某个类的对象或某些类中的一个类的对象,如果是则返回True,否则返回False,type(obj) 返回对象的类型

继承/派生

继承是指从已有的类中派生出新的类,新类具有原类的行为,并能扩展新的行为

派生类就是从一个已有类中衍生成新类,在新类上可以添加新的属性和行为

作用:1.用继承派生机制,可以将一些共有功能加在基类中,实现代码的共享

      2、在不改变基类的代码的基础上改变原有的功能

名词:基类(base class)/超类(super class)/父类(father class)

     派生类(derived class) / 子类(child class)

单继承

单继承:

  语法:

    class 类名(基累名):

      语句块

  说明:单继承是指由一个基类衍生出的新的类

class Derived_Class_Name(Base_Class_Name1):
<statement-1>
.
.
<statement-N>

单继承实例

class Human:  # 人类的共性
def say(self, what):
print("say:", what)

def walk(self, distance):  # 走路
print("走了", distance, '公里')

class Student(Human):
def study(self, subject):
print("正在学习:", subject)

class Teacher(Student):
'''说话,行走,教学'''
def teach(self, subject):
print("正在教:", subject)

h1 = Human()
h1.say('天气晴了')
h1.walk(5)
print('---------------')
s1 = Student()
s1.walk(4)
s1.say('感觉有点累')
s1.study('Python')
print('===============')
t1 = Teacher()
t1.walk(6)
t1.say('吃点啥好呢')
t1.teach('面向对象')
t1.study('转魔方')

继承说明:python3 任何类都直接或间接的继承自object类,object 类是一切类的超类

类的__base__属性:__base__属性用来记录此类的基类

覆盖

覆盖是指在有继承关系的类中,子类中实现了与基类同名的方法,在子类的实例调用该方法时,实际调用的是子类中的覆盖版本

class A:
def works(self):
print("A.works被调用")

class B(A):
"""B类继承A类"""
def works(self):
print("B.works被调用")

a = A()
a.works()  # A.works被调用

b = B()
b.works()  # B方法被调用

用类名显式调用

子类对象显式调用基类(被覆盖)方法的方式:基类名.方法名(实例, 实际调用传参)

class A:
def works(self):
print("A.works被调用")

class B(A):
''' B类继承自A类'''
def works(self):
print("B.works被调用")

b = B()
b.works()  # B.works被调用
A.works(b)  # 用类名显式调用, A.works被调用

super函数

super(cls, obj)返回绑定超类的实例(要求obj必须是cls类型的实例),一般obj就是selfcls一般就是当前类的类名

super()  返回父类的实例,

常见用法:super(__class__, 实例方法的第一个参数),必须在方法内调用,一般super(class_name, self).父类方法  # 中间参数可以省略,如下例

作用:借助super() 返回的实例间接调用其父类的覆盖方法

super().父类方法()

class A:
def works(self):
print("A.works被调用")

class B(A):
"""B类继承自A类"""
def works(self):
print("B.works被调用")

def super_work(self):
self.works()  # B.works被调用
super(B, self).works()  # A.works被调用
super().works()  # A.works被调用

b = B()
b.works()  # B.works被调用
super(B, b).works()  # A.works被调用
b.super_work()  # ...
# B.works被调用
# A.works被调用
# A.works被调用

super().works()  # 出错,只能在方法内调用

显式调用基类的初始化方法

当子类中实现了 __init__方法,基类的构造方法并不会被调用,def __init__(self, ...)

super().__init__(n,a)    # 参数不填的话,默认调用父类的所有初始化参数

class Human:
def __init__(self, n, a):
self.name, self.age = n, a
print("Human的__init__方法被调用")

def infos(self):
print("姓名:", self.name)
print("年龄:", self.age)

class Student(Human):
def __init__(self, n, a, s=0):
super().__init__(n, a)  # 显式调用父类的初始化方法
self.score = s  # 添加成绩属性
print("Student类的__init__方法被调用")

def infos(self):
super().infos()  # 调用父类的方法
print("成绩:", self.score)

s1 = Student('小张', 20, 100)
s1.infos()

多继承

class DerivedClassName(Base1, Base2, Base3):
<statement-1>
.
.
<statement-N>

需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,python从左至右搜索 即方法在子类中未找到时,从左到右查找父类中是否包含方法。

class people:
name = ''
age = 0
__weight = 0

def __init__(self, n, a, w):
self.name = n
self.age = a
self.__weight = w

def speak(self):
print("%s 说: 我 %d 岁。" % (self.name, self.age))

class speaker():
topic = ''
name = ''

def __init__(self, n, t):
self.name = n
self.topic = t

def speak(self):
print("我叫 %s,我是一个演说家,我演讲的主题是 %s" % (self.name, self.topic))

# 多继承
class sample(speaker, people):
a = ''

def __init__(self, n, a, w, t):
# 调用父类的构函数
people.__init__(self, n, a, w)
speaker.__init__(self, n, t)

test = sample('凌逆战', "大学生", 23, 'python')
test.speak()  # 方法名重复了,默认调用的是括号中排前地父类的方法
# 我叫 凌贤鹏,我是一个演说家,我演讲的主题是 python

方法重写

如果父类方法的功能不能满足需求,可以在子类重写父类的方法

class parent:  # 定义父类
def my_method(self):
print("调用父类的方法")

class child(parent):  # 定义子类
def my_method(self):
print("调用子类方法")

c = child()  # 子类实例

# 子类调用重写方法
c.my_method()       # 调用子类方法

# 用子类对象调用父类已被覆盖的方法
super(child, c).my_method()
# 调用父类的方法

super()函数是用于调用父类(超类)的方法

Python 子类继承父类构造函数说明

类属性与方法

类的私有属性

__private_attrs:两个写划线开头,声明该属性为私有类,不能在类地外部被使用或直接访问,在类内部的方法使用时self.private_attrs

类的方法

在类地内部,使用def关键字来定义一个方法,与一般函数定义不同,类方法必须包含self,且为第一个参数,self代表的是类的实例。

self的名字并不是规定死的,也可以是其他的,但最好按照规定用self

类的私用方法

__private_method:两个下划线开头,声明该方法为私有方法,只能在类的内部调用 ,不能在类地外部调用。self.__private_methods

类的私有属性

class JustCounter:
__secretCount = 0  # 私有变量
publicCount = 0  # 公开变量

def count(self):
self.__secretCount += 1
self.publicCount += 1
print(self.__secretCount)

counter = JustCounter()
counter.count()     # 1
counter.count()     # 2
print(counter.publicCount)  # 2
print(counter.__secretCount)
# 报错,实例不能访问私有变量
# Traceback (most recent call last):
#   File "test.py", line 16, in <module>
#     print (counter.__secretCount)  # 报错,实例不能访问私有变量
# AttributeError: 'JustCounter' object has no attribute '__secretCount'

类的私有方法

class Site:
def __init__(self, name, url):
self.name = name  # public
self.__url = url  # private

def who(self):
print('name: ', self.name)
print('url : ', self.__url)

def __foo(self):  # 私有方法
print('这是私有方法')

def foo(self):  # 公共方法
print('这是公共方法')
self.__foo()

x = Site('菜鸟教程', 'www.runoob.com')
x.who()  # 正常输出
x.foo()  # 正常输出
x.__foo()  # 报错

类的专有方法

  • __init__:构造函数,在生成对象时调用
  • __del__ : 析构函数,释放对象时使用
  • __repr__ : 打印,转换
  • __setitem__ : 按照索引赋值
  • __getitem__: 按照索引获取值
  • __len__: 获得长度
  • __cmp__: 比较运算
  • __call__: 函数调用
  • __add__: 加运算
  • __sub__: 减运算
  • __mul__: 乘运算
  • __div__: 除运算
  • __mod__: 求余运算
  • __pow__: 乘方

运算符重载

class Vector:
def __init__(self, a, b):
self.a = a
self.b = b

def __str__(self):
return 'Vector (%d, %d)' % (self.a, self.b)

def __add__(self, other):
return Vector(self.a + other.a, self.b + other.b)

v1 = Vector(2, 10)
v2 = Vector(5, -2)
print(v1 + v2)      # Vector(7,8)

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: