前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >面向对象进阶

面向对象进阶

作者头像
GH
发布2019-12-16 15:14:25
4160
发布2019-12-16 15:14:25
举报

面向对象进阶

Wisdom is knowing what to do next , virtue is doing it .

classmethod 和 staticmethod

classmethod

装饰给类内部的方法,使该方法绑定给类使用。由类调用,将类作为第一个参数传入方法,不影响对象对该方法的调用。

代码语言:javascript
复制
class People:
    def __init__(self,name,age):
        self.name = name
        self.age = age
        print(self)

    @classmethod
    def tell_info(cls):
        print(cls)#这里只是说明这个方法已经绑定给了类,所以其参数是类
        print('此处是类方法。。。')

p = People('tank',18)
p.tell_info()
#<__main__.People object at 0x00000272647D8A20>
# <class '__main__.People'>
# 此处是类方法。。。

staticmethod

是一个装饰器,可以装饰给类内部的方法,使该方法不绑定给对象,也不绑定给类使其变成一个普通的函数,但是不改变其调用方式。(__class__对象的属性,获取当前对象的类)

小练习

1、定义MySQL类 1.对象有id、host、port三个属性

  2.定义工具create_id,在实例化时为每个对象随机生成id,保证id唯一   3.提供两种实例化方式,方式一:用户传入host和port 方式二:从配置文件中读取host和port进行实例化

代码语言:javascript
复制
#下面代码仅给出了实例化的两种方式,和ID的产生
import hashlib,uuid,settings#settings为配置文件(配置文件其实就是一个自定义的模块)
class Teacher:
    def __init__(self,user,pwd):#通过对象的绑定方法产生一个对象(对象名 = 类(参数))
        self.user = user
        self.pwd = pwd

    def index(self):
        if self.user == 'tahk' and self.pwd == '123':
            print('验证通过,显示主页。。。')

    @classmethod
    def login_auth_from_settings(cls):#通过配置文件的方式产生一个对象(通过类的绑定方法产生一个对象)
        obj = cls(settings.USER,settings.PWD)
        return obj

    @staticmethod
    def create_id():
        uuid_obj = uuid.uuid4()
        md5 = hashlib.md5()
        md5.update(str(uuid_obj).encode('utf8'))
        return md5.hexdigest()

obj = Teacher.login_auth_from_settings()#通过配置文件产生对象需要单独调用实例化方法
obj.index()
tea1 = Teacher('tank', '123')
print(tea1.create_id())
tea1.index()
print(Teacher.create_id())

isinstance 和 issubclass

isinstance

isinstance******(参数1,参数2)返回bool值判断参数1(对象)是否是参数二(类)的实例。

issubclass

issubclass*****判断参数一(子类)是否是参数二(父类)的子类反射*******指通过字符串对对象或类的属性进行操作。

代码语言:javascript
复制
class Foo:
    pass

class Goo(Foo):
    pass


foo_obj = Foo()
print(isinstance(foo_obj, Foo))
print(isinstance(foo_obj, Goo))  # False
print(issubclass(Goo, Foo))  # True

反射

反射指通过字符串对对象或类的属性进行操作。

hasattr:通过判断该字符串是否是对象或类的属性。

getattr:通过字符串获取对象或类的属性。

setattr:通过字符串设置对象或类的属性,如果属性不存在会为对象添加属性。

delattr:通过字符串删除对象或类的属性。

代码语言:javascript
复制
class People:#创建一个类
    country = 'China'

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

p = People('tank',17,'male')
#普通方式
print('name' in p.__dict__)#判断name是否是对象的属性值
#hasattr
print(hasattr(p,'name'))
print(hasattr(People,'country'))
#获取属性值
#普通方式
print(p.__dict__.get('name'))
#getattr
print(getattr(p,'name','jason_sb'))#如果有值则返回属性值,如果没有则返回最右侧的这个值
print(getattr(People,'country2','China'))
#为对象或类添加属性
#普通方式
p.level = 10
print(p.level)
#setattr
setattr(p,'sal','3.0')
print(hasattr(p,'sal'))
#删除对象的属性
#普通方式
del p.level
print(hasattr(p,'level'))
#delattr
delattr(p,'sal')
print(hasattr(p,'asl'))
print(p.__dict__.get('level'))

反射小练习:使用反射实现输入属性的名字就可以执行类或对象中的方法。

代码语言:javascript
复制
class Movie:
    def input_cmd(self):
        print('输入命令:')
        while True:
            cmd = input('请输入方法名').strip()
            if hasattr(self,cmd):
                method = getattr(self,cmd)
                method()
    def upload(self):
        print('电影开始上传')

    def download(self):
        print('电影开始下载')

movie_obj = Movie()
movie_obj.input_cmd()

魔法方法

魔法方法(类的内置方法):凡是在类内部定义,以__开头__结尾都称之为魔法方法,又称类的内置方法, 会在某些条件成立的情况下触发。 __init__:在调用类时触发。 __str__:会在打印对象时触发,必须要return一个字符串类型的值。 __str__应用:打印一个列表等等。 __del__:会在程序执行结束时触发,对象销毁,该方法会在最后被执行和其定义的位置无关。 __getattr__:会在对象.属性时,属性没有的情况下触发,如果没有默认返回None,我们可以加return 我们想要的值。 __getattribute__:不管属性有没有都会触发,如果和__getattr__同时出现,则只执行前者(__getattribute__) __setattr__:会在对象.属性 = 属性值 时触发,出发时外部的对象添加属性赋值就没用了,属性赋值在内部进行。 __call__:会在对象被调用时触发。 __new__:会在__init__执行前触发,真正的实例化对象就是通过object类中的__new__进行的,__new__会创建一个空的实例化对象。

代码语言:javascript
复制
class Foo(object):

    def __new__(cls, *args, **kwargs):
        print(cls)
        return object.__new__(cls)#通过object产生一个空对象

    def __init__(self):
        print('在调用类时触发。。。')

    def __str__(self):
        print('在打印时触发。。。')
        return 'xiaohua'

    def __del__(self):
        print('对象被销毁前执行该方法')

    def __getattr__(self, item):
        print('会在对象.属性时,属性没有的情况下触发')
        print(item)
        #默认返回None,若想打印属性的结果,必须return一个值
        return 1

    def __setattr__(self, key, value):
        print('会在对象.属性 = 属性值 时触发...')
        print(key,value)
        print(type(self))
        print(self,111)
        self.__dict__[key] = value

    def __call__(self, *args, **kwargs):
        print(self)
        print('调用对象时触发该方法...')

foo_obj = Foo()
print(foo_obj.__class__)
foo_obj.x = 10
#print(foo_obj.x)
print(foo_obj)

小练习:使用魔法方法和open,实现with open的功能。

代码语言:javascript
复制
class MyFile:
    def __init__(self,file_name,mode = 'r',encoding = 'utf8'):
        self.file_name = file_name
        self.mode = mode
        self.encoding = encoding

    def file_open(self):
        self.f = open(self.file_name,self.mode,encoding=self.encoding )

    def file_read(self):
        res = self.f.read()
        print(f'''
        当前文件名称:{self.file_name}
        当前文件数据:{res}
        ''')

    def __del__(self):
        self.f.close()
        print('文件关闭成功')

f = MyFile('biji.txt')
f.file_open()
f.file_read()

单例模式

单例模式指的是单个实例,实例指的时调用类产生的对象。

​ 实例化多个对象会产生不同的内存地址,单例可以让所有调用者, 在调用类产生对象的情况下都指向同一份内存地址。 例如: 打开文件。

​ 单例的目的: ​ 为了减少内存的占用。

代码语言:javascript
复制
class File:
    __instance = None
    # 单例方式1
    @classmethod
    def singleton(cls,file_name):
        if not cls.__instance:
            obj = cls(file_name)
            cls.__instance = obj
        return cls.__instance

    def __init__(self,file_name,mode='r',encoding = 'utf8'):
        self.file_name = file_name
        self.mode = mode
        self.encoding = encoding

    def open(self):
        self.f = open(self.file_name,self.mode,encoding=self.encoding)

    def read(self):
        res = self.f.read()
        print(res)

    def close(self):
        self.f.close()

file1 = File.singleton('biji.txt')#此处必须要调用这个方法才行
print(file1)
file2 = File.singleton('biji.txt')
print(file2)
代码语言:javascript
复制
class File:
    __instance = None
    # 单例方式2
    def __new__(cls, *args, **kwargs):
        if not cls.__instance:
            cls.__instance = object.__new__(cls)
        return cls.__instance

    def __init__(self,file_name,mode='r',encoding = 'utf8'):
        self.file_name = file_name
        self.mode = mode
        self.encoding = encoding

    def open(self):
        self.f = open(self.file_name,self.mode,encoding=self.encoding)

    def read(self):
        res = self.f.read()
        print(res)

    def close(self):
        self.f.close()

file1 = File('biji.txt')#此处必须要调用这个方法才行
print(file1)
file2 = File('biji.txt')
print(file2)
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-10-12 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 面向对象进阶
    • classmethod 和 staticmethod
      • classmethod
      • staticmethod
    • isinstance 和 issubclass
      • isinstance
      • issubclass
    • 反射
      • 魔法方法
        • 单例模式
        相关产品与服务
        云数据库 MySQL
        腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档