Python类和对象

封装继承多态

类和对象

定义

class 大写开头的类名:
      pass
      变量和方法

类成员的顺序没有影响,成员之间可以调用

  1. 变量:类变量,实例变量
  2. 方法

类变量 :定义在类里面的变量
实例变量:__init__方法里面的变量

动态语言,
类变量可以随时定义/赋值和删除
实例变量也是
实例方法至少定义一个参数,就是self

构造方法__init__()在里面可以定义变量,必须有一个self参数

在这里插入代码片

类的作用:

  1. 定义变量
  2. 创建对象
  3. 派生子类

对象的产生和使用

p = P("zhang",22)

可以给对象添加实例变量,也可以随时删除。

p.skill = "swimming"
del p.name

增加方法:

def method(self):
    pass
p.fuc = method
# 调用方法
p.fuc(p)

# 或者直接lambda表达式
p.bar = lambda self: print(self)
# 调用方法
p.bar(p)

# 或者自动绑定第一个参数,借助模块
def method(self):#可以有多个参数啊
    print(self)
from types import MethodType
p.intro = MethodType(method, p)
p.intro()   

方法

通过类调用实例方法

Person.test(p)# 此时需要传入self参数,可以是对象,也可以是字符串等

类方法和静态方法

区别:类方法的第一个参数会自动绑定类本身(cls),静态方法不会自动绑定
类方法:@classmethod修饰
静态方法:@staticmethod修饰

class Bird:
    @classmethod
    def fly(cls):
          print(cls)
    @staticmethod
    def info(p):
          print("静态方法",p)
Bird.fly()
Bird.info("abc")
b = bird()

一般可以用函数代替,但是如工厂模式下,会用到静态方法类方法

@函数装饰器

@函数A 修饰函数B,就是:

  1. B作为参数传给A
  2. 将函数B替换为上一步的返回值

类是一个命名空间,里面也可以放执行语句

成员变量

类变量和实例变量

定义在类内的变量
不能直接访问,通过类名来访问,通过对象也可以

在成员方法中不能修改类变量的值,这样会创建新的实例变量

使用property函数定义属性

property可以有四个参数:可读,可写,可删,文档

class Rect:
    def __init__(self, length, height):
        self.length = length
        self.height = height
    def setsize(self, size):
        self.length,self.height = size
    def getsize(self):
        return self.length,self.height
    def delsize(self):
        self.length,self.height = 0,0
    size = property(getsize, setsize,  delsize , 'abc这是看长宽的方法')
print(Rect.size.__doc__)
r = Rect(3,3)
print(r.size)
r.size = 9,7
print(r.size)

也可以用@property修饰器修饰方法
@property修饰默认有get方法
具体略

隐藏和封装

成员命名以双下划线开头就是隐藏了
实际上还是可以可以调用:
u._User__hide()

class User:
    def getname(self):
        return self.__name
    def setname(self, name):
        if len(name)>8:
            raise ValueError('太长了')
        self.__name = name
    name = property(getname, setname)
u =User()
u.name = "abcd"

类的继承

子类可以有多个父类
没有继承的默认继承Object类

class Son(Super1, Super2):
    pass

重写

直接重写就可以了

子类中调用被重写的父类方法

# 子类中
def bar():
    self.foo()# 重写的方法
    Parent.foo(self)# 被重写的方法

super调用父类构造方法

子类重写了父类的构造方法,必须调用父类的构造方法

# 子类中
def __init__(self, s, f, a):
    super().__init__(s)
    Customer.__init__(self,f,a)

Python的动态性

动态属性和__slots__

如果类可以随意增加某个实例实例方法,不安全,可以通过slots属性改进
__slots__是元组,列出来可以增加的所有属性和方法的名字

class Dog:
    __slots__=('name','age','walk')
    可以是方法和变量

对子类无效,子类假如也设置slots属性为空,则和父类一样只能创建那几个

为所有实例添加方法:
通过为类添加方法实现

  1. 定义一个方法
  2. 关联到类
# 主方法中
def walk_func:
    pass
Cat.walk = walk_func

slots不会限制这种通过类来动态添加属性或方法

使用type()函数定义类

type()函数可以创建type对象,type对象就是类
所以用type()函数定义类

def fn(self):
    print(1123,self.age)

Dog = type('Dog', (object,), dict(walk = fn, age =6))
d = Dog()
print(type(d))
print(type(Dog))
d.walk()
print(Dog.age)

三个参数:

  1. 类名
  2. 父类元组,多个逗号
  3. 参数字典

使用meatclass

可以在创建类是约束类必须有哪些方法,略

多态

多态性

同一个变量x,可能在不同时候指向不同对象(比如鸟对象和猴子对象),从而执行一个同名方法实际的动作不同

类型检查

检查cls是不是后一个类或者后一个元组中的类的的子类
检查obj是不是后一个类或者后一个元组中的类的对象

issubclass(cls, class_or_tuple)
isinstance(cls, class_or_tuple)

issubclass(str, (list,tuple)) #False

返回True或者False

枚举类

入门

定义枚举类方法:

  • 通过Enum直接列出枚举值—简单的
  • 继承Enum基类派生出枚举类—复杂的
## 为什么报错了
import enum
Season = enum.Enum(Season,('SPRING','SUMMER','FALL'))

Season看作类,
Season.SPRING看作对象,也可以Season[[‘SPRING’], Season(1)
对象有两个属性:namevalue(从一开始增加),
类的属性: __members__(是一个包含所有枚举实例的字典)

for name , member in Season.__members__.items()

访问:

print(Season.SPRING)//
print(Season.SPRING.name)
print(Season.SPRING.value)

继承Enum,可以定义额外的方法

import enum
class Orientation(enum.Enum):
    EAST = '东'
    WEST = '西'
    def info(self):
        print(self.value,self.name)
print(Orientation.WEST.name)
Orientation.WEST.info()

枚举类的构造器

定义了构造器以后,定义实例时就必须指定值

import enum
class Orientation(enum.Enum):
    EAST = '东','前面是东'
    WEST = '西','后面是西'
    def __init__(self, orient, disc):
        self._orient = orient
        self._disc = disc
    @property
    def orient(self):
        return self._orient
    @property
    def disc(self):
        return self._disc
    def info(self):
        print(self.value,self.name)
print("west的名字:",Orientation.WEST.name)
print('值:',Orientation.WEST.value)
print('orient:',Orientation.WEST.orient)
print('disc:',Orientation.WEST.disc)
'''
west的名字: WEST
值: ('西', '后面是西')
orient: 西
disc: 后面是西'''

其他

查看一个类的父类
查看子类

A.__bases__
A.__subclasses__
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值