classmethod装饰器,staticmethod,面向对象高级,魔法方法,单例模式(面试30%会问)

1.classmethod

classmethod 翻译 :一个类方法

classmethod是一个装饰器,可以装饰给类内部的方法,使该方法绑定给类来使用。
        - 对象的绑定方法特殊之处
            由对象来调用,会将对象当作第一个参数传给该方法。

        - 类的绑定方法特殊之处
            由类来调用,会将类当作第一个参数传给该方法。

staticmethod:
    staticmethod是一个装饰器,可以装饰给类内部的方法,使该方法即不绑定给对象,也不绑定给类。

代码

@property

class Student(object):
    def __init__(self, score):
        self._score = score
    @property
    def score(self):
        return self._score
    @score.setter
    def score(self, value):
        '''这里对score进行判断、处理的操作'''
        self._score = value
通过这样的处理,实例对象self._score属性不会被任意改变,可以使用score.setter进行控制
调用方式:
    
s = Student(80)
'''查看分数'''
s.score
'''修改分数'''
s.score(100)



@classmethod
简单来说,classmethod就是讲类中的方法变成类方法
@staticmethod  将类外面的函数 拿到里面
class Student:               # 静态方法
    @staticmethod            # 可以把外面的函数拿到类里面写
    def login(usr,pwd):      # 相当于将他变成普通方法,可以不用self传参。通过类名点方法名调用
        print('in login',usr,pwd)
Student.login('user','pwd')
# 列1:
class TutorialPipeline(object):
    def __init__(self, redis_host, redis_port):
        self._redis_host = redis_host
        self._redis_port = redis_port

    @classmethod
    def from_crawler(cls, crawler):
        return cls(crawler.settings.get('REDIS_HOST'), crawler.settings.get('REDIS_PORT'))
该类方法的功能为,返回一个实例对象

#列2
from datetime import date
class Student(object):

    def __init__(self, name, age):
        self.name = name
        self.age= age
    
    @classmethod
    def from_year(cls, name, birth_year):
        return cls(name, date.today().year - birth_year)


student1 = Student("小王", 15)
student2 = Studeng("小李", 2006)

print(student1.age)
print(student2.age)
复制代码
从上面可以看出,from_year这个函数是构造student这个对象的另外一个类方法。但是使用了不同的传参手段和处理方式。
## 列3

import hashlib
import uuid
import settings
class Teacher:
    def __init__(self, user, pwd):
        self.user = user
        self.pwd = pwd

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

    @classmethod
    def login_auth_from_settings(cls):
        obj = cls(settings.USER, settings.PWD)
        return obj  # Teacher() ---> return = obj

    @staticmethod
    def create_id():
        # 生成一个唯一的id字符串
        uuid_obj = uuid.uuid4()
        md5 = hashlib.md5()
        md5.update(str(uuid_obj).encode('utf-8'))
        return md5.hexdigest()


obj = Teacher.login_auth_from_settings()
obj.index()

tea1 = Teacher('tank', '123')
tea1.index()



import uuid  # 是一个加密模块,uuid4通过时间戳生成一个世界上唯一的字符串。
if __name__ == '__main__':
    print(type(uuid.uuid4()))

print(Teacher.create_id())
tea1 = Teacher('tank', '123')
print(tea1.create_id())

2.staticmethod

__class__: 对象的属性,获取该对象当前的类。

- isinstance(参数1, 参数2):
    python内置的函数,可以传入两个参数,用于判断参数1是否是参数2的一个实例。

    **** 判断一个对象是否是一个类的实例。


- issubclass(参数1, 参数2):
    python内置的函数,可以传入两个桉树,用与判断参数1是否是参数2的子类。

    ***判断一个类是否是另一个类的子类

代码

class Foo:
    @staticmethod
    def func(res):
        print(res)

# 对象调用非绑定方法
obj = Foo()
obj.func(123)

# 类调用非绑定方法
Foo.func(1234)





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

3.面向对象高级:

  • isinstance
  • issubclass
  • 反射: - 魔法方法(类的内置方法)
反射: 指的是通过“字符串”对 对象或类的属性进行操作。
    - hasattr: 通过字符串,判断该字符串是否是对象或类的属性。
    - getattr: 通过字符串,获取对象或类的属性。
    - setattr: 通过字符串,设置对象或类的属性。
    - delattr: 通过字符串,删除对象或类的属性。

代码

反射小练习:
'''
class Movie:
    def input_cmd(self):
        print('输入命令:')
        while True:
            cmd = input('请输入执行的方法名:').strip()

            # 若用户输入的cmd命令是当前对象的属性
            if hasattr(self, cmd):
                method = getattr(self, cmd)
                method()
            else:
                print('命令错误,请重新输入!')

    def upload(self):
        print('电影开始上传...')

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


movie_obj = Movie()
movie_obj.input_cmd()

4.魔法方法

魔法方法:
    凡是在类内部定义,以“__开头__结尾”的方法都称之为魔法方法,又称“类的内置方法”。
    魔法方法会在某些条件成立时触发。

    __init__: 在调用类时触发。
    __str__: 会在打印对象时触发。
    __del__: 对象被销毁前执行该方法,该方法会在最后执行。
    __getattr__: 会在对象.属性时,“属性没有”的情况下才会触发。
    __setattr__: 会在 “对象.属性 = 属性值” 时触发。
    __call__: 会在对象被调用时触发。
    __new__: 会在__init__执行前触发。

代码

以下代码知:先创建一个jison雨后的小故事.txt 文件。
class MyFile(object):
    def __init__(self, file_name, mode='r', encoding='utf-8'):
        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 close(self):
    #     self.f.close()
    def __del__(self):
        self.f.close()
        print('文件关闭成功!')

f = MyFile('jason雨后的小故事.txt')
f.file_open()
f.file_read()

print('程序结束,对象被销毁!')  #

5.单例模式(面试30%会问)

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

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

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

单例模板:

# classmethod 单例模式
# class Singleton:
#
#     __instance = None
#
#     @classmethod
#     def singleton(cls):
#
#         if not cls.__instance:
#
#             cls.__instance = cls()
#
#         return cls.__instance


# __new__:
# class Singleton:
#
#     __instance = None
#
#     def __new__(cls, *args, **kwargs):
#
#         if not cls.__instance:
#
#             # 造一个空对象
#             cls.__instance = object.__new__(cls)
#
#         return cls.__instance
#
#
# obj1 = Singleton()
# obj2 = Singleton()
# obj3 = Singleton()
# print(obj1)
# print(obj2)
# print(obj3)

代码:

从配置文件中获取相同的文件。
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='utf-8')
    	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()
obj1 = File('jason雨后的小故事.txt')
obj2 = File('jason雨后的小故事.txt')
obj3 = File('jason雨后的小故事.txt')
print(obj1)
print(obj2)
print(obj3)



方法二:
class File:

    __instance = None

    # 单例方式2:
    def __new__(cls, *args, **kwargs):
        # cls.__new__(cls, *args, **kwargs)
        if not cls.__instance:
            cls.__instance = object.__new__(cls)
        return cls.__instance

    def __init__(self, file_name, mode='r', encoding='utf-8'):
        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()

# 方式2:
obj1 = File('jason雨后的小故事.txt')  # singleton(cls)
obj2 = File('jason雨后的小故事.txt')  # singleton(cls)
obj3 = File('jason雨后的小故事.txt')  # singleton(cls)
print(obj1)
print(obj2)
print(obj3)

class Student():
    def __new__(cls, name,height):
        print('class.__new__called')
        if not hasattr(cls,'_instance'):
            cls.instance = object.__new__(cls)

    def __init__(self,name,height):
        print('class,__init__called')
        self.name = name
        self.height = height

        def __str__(self):
            return 'The height of student %s is %s' %(self.name,self.height)


if __name__ == '__main__':
    xiaoming = Student('xiaoming',111)
    print(xiaoming)
    jack = Student('Jack',188)
    print(jack)

    print(xiaoming)

    print(id(xiaoming))
    print(id(jack))
#结果:
class.__new__called
None
class.__new__called
None
None
140724186201312
140724186201312

原文地址:https://www.cnblogs.com/WQ577098649/p/11662753.html