python中的类

面向对象是一种思想而不是非得用类定义,该思想在于将重复的属性和行为分离出来,所以即使用函数也可以实现面向对象。

# 用函数实现面向对象思想
def school(name,addr,type):
    def init(name, addr, type):
        sch = {
            'name': name,
            'addr': addr,
            'type': type,
            'kao_shi': kao_shi,
            'zhao_sheng': zhao_sheng,
        }
        return sch
    def kao_shi(school):
        print('%s 学校正在考试' %school['name'])
    def zhao_sheng(school):
        print('%s %s 正在招生' %(school['type'],school['name']))
    return  init(name,addr,type)

s1=school('北大','北京','公立学校')
print(s1)
print(s1['name'])

s1['zhao_sheng'](s1)

s2=school('清华','北京','公立学校')
print(s2)
print(s2['name'],s2['addr'],s2['type'])
s2['zhao_sheng'](s2)

由于用函数实现不够方便,
python等语言帮我们提供了类这个概念用来方便实现面向对象编程。

# 在Python中,定义类是通过class关键字:
'''
1.数据属性
2.函数属性
'''
class Chinese:   # 定义类 类名一般首字母大写
    country='China'    # 类的数据属性 也称:属性
    def __init__(self,name):    # 构造函数  
        self.name=name          #  初始化实例的数据属性

    def play_ball(self,ball):   # 类的函数属性 也称:方法
        print('%s 正在打 %s' %(self.name))
#查看类的属性
print(Chinese.country)

#修改类的属性
Chinese.country='panama'
print(Chinese.country)

# 实例化类的对象
p1=Chinese('alex')
# 用内置的__dict__打印实例的属性字典
print(p1.__dict__)
print(p1.country)

#增加属性
Chinese.groups='汉族'

print(Chinese.groups)
print(p1.groups)

#删除
del Chinese.groups
del Chinese.country
print(Chinese.__dict__)
print(Chinese.country)


# 增加函数属性
def eat_food(self,food):
    print('%s 正在吃%s' %(self.name,food))

Chinese.eat=eat_food

print(Chinese.__dict__)
p1.eat('面')


def test(self):
    print('test')

# 替换函数
Chinese.play_ball=test
p1.play_ball()# Chinese.play_ball(p1)

类的属性与实例属性易懵点

class Chinese:
    country='China'
    def __init__(self,name):
        self.name=name

    def play_ball(self,ball):
        print('%s 正在打 %s' %(self.name,ball))
p1=Chinese('alex')
#为P1对象增加country属性,类的country属性不变
print(p1.country)       # 输出China
p1.country='Japan'
print(Chinese.country)   # China

class Chinese:
    country='China'
    l=['a','b']
    def __init__(self,name):
        self.name=name

    def play_ball(self,ball):
        print('%s 正在打 %s' %(self.name,ball))
p1=Chinese('ndk')
print(p1.l)      #['a', 'b']
#为P1对象增加l属性,类的l属性不变
p1.l=[1,2,3]
print(Chinese.l)      # ['a', 'b']
# pi对象的属性字典增加了l,
print(p1.__dict__)     #  {'name': 'ndk', 'l': [1, 2, 3]}
p1.l.append('c')
print(p1.__dict__)      #  {'name': 'ndk', 'l': [1, 2, 3, 'c']}
print(Chinese.l)      # 类的l列表任然不变 ['a', 'b']

#直接append方式没有生产对象的属性,append直接修改到类的属性中去了
p1.l.append('c')
print(Chinese.l)   #输出 ['a', 'b', 'c']

# 调用类内还是类外?
# 不用对象或类调用属性的话,解释器不在__dict__字典中查找,直接在全局中找。
country='中国-------------------'
class Chinese:
    country='中国'
    def __init__(self,name):
        self.name=name
        print('--->',country)     #此处不是用类/对象调用country,则调用外部country

    def play_ball(self,ball):
        print('%s 正在打 %s' %(self.name,ball))

print(Chinese.__dict__)   #{'__module__': '__main__', 'country': '中国', '__init__': <function Chinese.__init__ at 0x00000246E3A40950>, 'play_ball': <function Chinese.play_ball at 0x00000246E4AB01E0>, '__dict__': <attribute '__dict__' of 'Chinese' objects>, '__weakref__': <attribute '__weakref__' of 'Chinese' objects>, '__doc__': None}
print(Chinese.country)  #中国
p1=Chinese('alex')     #输出:---> 中国-------------------
print('实例--------》',p1.country)  #实例--------》 中国

实例属性的增删改查

class Chinese:
    country='China'
    def __init__(self,name):
        self.name=name

    def play_ball(self,ball):
        print('%s 正在打 %s' %(self.name,ball))
p1=Chinese('ndk')
print(p1.__dict__)

#查看
print(p1.name)
print(p1.play_ball)

#增加
p1.age=18
print(p1.__dict__)
print(p1.age)

#不要修改底层的属性字典
p1.__dict__['sex']='male'
print(p1.__dict__)
print(p1.sex)

#修改
p1.age=19
print(p1.__dict__)
print(p1.age)

#删除
del p1.age
print(p1.__dict__)

类的静态属性,静态方法,类方法

#静态方法:@property  将方法修饰为属性
#静态方法@staticmethod  供实例/类调用,不能调用类属性和方法,与类内一般函数相比无self参数,当类内工具包使用
#类方法:@classmethod 将方法修饰为类方法,供实例和类直接调用,默认参数为cls,无self参数
class Room:
    tag=1
    def __init__(self,name,owner,width,length,heigh):
        self.name=name
        self.owner=owner
        self.width=width
        self.length=length
        self.heigh=heigh

    @property
    def cal_area(self):
        print('%s 住的 %s 总面积是%s' % (self.owner,self.name, self.width * self.length))
        return  self.width * self.length

    @classmethod
    def tell_info(cls,x):
        print(cls)
        print('--》',cls.tag,x)  #   print('--》',Room.tag)

    def tell_info(self):
        print('---->',self.tag)

    @staticmethod
    def wash_body(a,b,c):
        print('%s %s %s正在洗澡' %(a,b,c))

    def test(x,y):
        print(x,y)

Room.wash_body('abc','123','qaz')

print(Room.__dict__)


r1=Room('公园','哈桑',100,100,100000)

print(r1.__dict__)
r1.wash_body('abc','123','qaz')

# Room.test(1,2) 输出 1 2
# r1.test(1,2)   报错 test() takes 2 positional arguments but 3 were given

类的继承

class Dad:
    '这个是爸爸类'
    money=10
    def __init__(self,name):
        print('爸爸')
        self.name=name
    def hit_son(self):
        print('%s 正在打儿子' %self.name)

class Son(Dad):
    money = 1000000000009
    def __init__(self,name,age):
        self.name=name
        self.age=age

    def hit_son(self):
        print('来自儿子类')
print(Son.money)    #1000000000009
# Son.hit_son()
print(Dad.__dict__)
print(Son.__dict__)
s1=Son('alex',18)
s1.hit_son()    # 来自儿子类
print(s1.money)   # 1000000000009
print(Dad.money)  # 10
print(s1.name)    # alex
print(s1.__dict__)  #{'name': 'alex', 'age': 18}
s1.hit_son()    # 来自儿子类

类的继承顺序

这里写图片描述
若有上图所示继承类的顺序:B,C继承自A;D继承自B;E继承自C;F继承自D,E;
则函数查找顺序为如下:

#coding:utf-8
class A:
    # def test(self):
    #     print('A')
    pass
class B(A):
    # def test(self):
    #     print('B')

    pass
class C(A):
    # def test(self):
    #     print('C')
    pass

class D(B):
    # def test(self):
    #     print('D')
    pass

class E(C):
    # def test(self):
    #     print('E')
    pass

class F(D,E):
    # def test(self):
    #     print('F')
    pass
f1=F()
f1.test()  
#经典类:F->D->B->A-->E
# 经典类:没有继承object的类
#新式类:均继承了object的类
# 在python3中全为新式类,可用方法解析序列__mro__查看继承类顺序
print(F.__mro__)

#F-->D->B-->E--->C--->A新式类

接口继承实现归一化

# 导入abc模块实现统一接口函数
import abc
# 标准类继承格式
class All_file(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def read(self):
        pass
# 用@abc.abstractmethod修饰类方法后子类继承该类时,必须重写该函数
    @abc.abstractmethod
    def write(self):
        pass

class Disk(All_file):
    def read(self):
        print('disk read')

    def write(self):
        print('disk write')

class Cdrom(All_file):
    def read(self):
        print('cdrom read')

    def write(self):
        print('cdrom write')


class Mem(All_file):
    def read(self):
        print('mem read')

    def write(self):
        print('mem write')

m1=Mem()
m1.read()
m1.write()

在子类用super函数中调用父类方法

class Vehicle1:
    Country='China'
    def __init__(self,name,speed,load,power):
        self.name=name
        self.speed=speed
        self.load=load
        self.power=power
    def run(self):
        print('开动啦')
        print('开动啦')
class Subway(Vehicle1):
        def __init__(self,name,speed,load,power,line):
           # Vehicle.__init__(self,name,speed,load,power)
           # super().__init__(name,speed,load,power)  #super(__class__,self).__init__(name,speed,load,power)
           super(Subway,self).__init__(name,speed,load,power)
           self.line=line
        def show_info(self):
            print(self.name,self.speed,self.load,self.power,self.line)
        def run(self):
            # Vehicle.run(self)
            super().run()
            print('%s %s 线,开动啦' %(self.name,self.line))
line13=Subway('北京地铁','10km/s',1000000000,'电',13)
line13.show_info()
line13.run()

print(line13.__class__)

反射的实现: hasattr getsttr setattr delattr

class BlackMedium:
    feture='Ugly'
    def __init__(self,name,addr):
        self.name=name
        self.addr=addr

    def sell_hourse(self):
        print('【%s】 正在卖房子,傻逼才买呢' %self.name)

    def rent_hourse(self):
        print('【%s】 正在租房子,傻逼才租呢' % self.name)

# 判断是否拥有该属性
print(hasattr(BlackMedium,'feture'))

# 或得该属性对应的值
print(getattr(BlackMedium,'feture'))

b1=BlackMedium('万成置地','天露园')
# b1.name--->b1.__dic__['name']
print(b1.__dict__)

# 设置属性
setattr(b1,'sb',True)
setattr(b1,'sb1',123)
setattr(b1,'name','SB')

# 删除属性
delattr(b1,'sb')

类中带双下划线的attr方法

class Foo:
    def __init__(self,name):
        self.name=name

    # 获取属性时触发
    def __getattr__(self, item):
        print('你找的属性【%s】不存在' %item)

    # 修改属性时触发
    def __setattr__(self, k,v):
        print('执行setattr',k,v)
        if type(v) is str:
            print('开始设置')
            # self.k=v #触发__setattr__
            self.__dict__[k]=v.upper()
        else:
            print('必须是字符串类型')

    # 删除属性时触发
    def __delattr__(self, item):
        print('不允许删除属性【%s】' %item)
        # print('执行delattr',item)
        # del self.item
        # self.__dict__.pop(item)

f1=Foo('alex')
f1.age=18 #触发__setattr__
print(f1.__dict__)
print(f1.name)
print(f1.age)
print(f1.gender)
print(f1.slary)
print(f1.__dict__)
del f1.name
print(f1.__dict__)

类的封装

#_*_coding:utf-8_*_
#在类中用单下划线_,或双下划线__封装内部属性,只能在内部用访问
#Python的封装是一种约定(实际任然可以在外部访问,这样相当于声明让别人不要在外部访问)
__author__ = 'Linhaifeng'

class People:
    __star='earth111111111111'
    __star1='earth1111111'
    __star2='earth111111111111'
    __star3='earth111111111111'
    def __init__(self,id,name,age,salary):
        print('----->',self.__star)
        self.id=id
        self.name=name
        self.age=age
        self.salary=salary

    def get_id(self):
        print('我是私有方法啊,我找到的id是[%s]' %self.id)

    #访问函数
    def get_star(self):
        print(self.__star)


p1=People('123123123123','alex','18',100000000)
# print(p1.__star)
print(People.__dict__)
# print(p1.__star)
print(p1._People__star)  # 在外部访问到了私有属性
#
p1.get_star()
p1.get_star()
  • 3
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值