目录
- Classmethod
- Staticmethod
- Isinstance
- Issubclass
- 反射
- 概念
- hasattr
- getattr
- setattr
- delattr
- 魔法方法
- 概念
__new__
__init__
__str__
__call__
__getattr__
__setattr__
__del__
- 单例模式
- 概念
- 目的
- 实现方式
Classmethod
- classmethod是一个装饰器, 用来装饰类内部的方法, 使得该方法绑定给类来使用
- 对象绑定方法的特殊之处: 由对象调用, 将对象作为第一参数传给该方法
- 类的绑定方法的特殊之处: 由类来调用, 将类作为第一参数传给该方法
Staticmethod
- staticmethod是一个装饰器, 用来装饰类内部的方法, 使得该方法既不绑定给对象, 也不绑定给类
# settings.py
USER = 'bigb'
PASSWORD = '123'
import uuid
import settings
import hashlib
class User:
def __init__(self, username, password):
self.username = username
self.password = password
def admin(self):
if not self.username == 'bigb' and self.password == '123':
print('请用管理员账户登录...')
return
print('显示管理员功能...')
@classmethod
def __from_settings(cls):
obj = cls(settings.USER, settings.PASSWORD)
return obj
@staticmethod
def creat_id():
uuid_obj = uuid.uuid4()
md5 = hashlib.md5()
md5.update(str(uuid_obj).encode('utf-8'))
return md5.hexdigest()
obj1 = User._User__from_settings()
obj1.admin() # 显示管理员功能...
obj2 = User('blake', '123')
obj2.admin() # 请用管理员账户登录...
print(obj2.creat_id()) # e249b25cdd1963a4949cc99d3ad46ff2
Isinstance
isinstance(args1, args2)
Python内置函数, 用于判断args1
(对象)是否是args2
(类)的一个实例
class Foo:
pass
foo_obj = Foo()
print(isinstance(foo_obj, Foo)) # True
Issubclass
issubclass(args1, args2)
Python内置函数, 用于判断args1
是否是args2
的子类
class ParentClass:
pass
class ChildClass(ParentClass):
pass
class OtherClass:
pass
print(issubclass(ChildClass, ParentClass)) # True
print(issubclass(OtherClass, ParentClass)) # False
反射
概念
- 反射指的是通过字符串对对象或类的属性进行操作
hasattr
hasattr(o, attrname)
判断o
(类或对象) 中是否有名字叫attrname
(字符串) 这样的一个属性
class Chinese:
country = 'China'
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
people = Chinese('bigb', '18', 'male')
print('name' in people.__dict__) # True
print(hasattr(people, 'name')) # True
getattr
getattr(o, attrname, default)
: 用来获取o
(对象或类) 中名叫attrname
(字符串) 的属性对象, 如果没有则返回默认值default
class Chinese:
country = 'China'
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
def say_slogan(self):
print('One China')
people = Chinese('bigb', '18', 'male')
people.say_slogan() # One China
getattr(people, 'say_slogan')() # One China
print(getattr(people, 'country')) # China
print(getattr(people, 'country1', 'China')) # China
class Movie:
def input_cmd(self):
while True:
cmd = input('请输入方法名: ')
if hasattr(self, cmd):
method = getattr(self, cmd)
method()
def upload(self):
print('电影开始上传...')
def download(self):
print('电影开始下载...')
movie_obj = Movie()
movie_obj.input_cmd()
setattr
setattr(o, attrname, value)
用来添加或修改o
(对象或类) 的属性:attrname = value
class Chinese:
country = 'China'
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
def say_slogan(self):
print('One China')
people = Chinese('bigb', '18', 'male')
# 修改
setattr(people, 'gender', 'female')
# 添加
setattr(people, 'province', 'Anhui')
print(people.gender) # female
print(people.province) # Anhui
delattr
delattr(o, attrname)
用来删除o
(对象或类) 中叫做attrname
(字符串) 的属性
class Chinese:
country = 'China'
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
def say_slogan(self):
print('One China')
people = Chinese('bigb', '18', 'male')
# 添加
setattr(people, 'province', 'Anhui')
# 删除
delattr(people, 'province')
print(people.province) # AttributeError: 'Chinese' object has no attribute 'province'
魔法方法
概念
- 在类内部定义, 以
__
开头__
结尾的方法的方法都称之为魔法方法, 又称为类的内置方法 - 魔法方法会在某些条件成立是触发
- 魔法方法都是object类内定义的方法
__new__
- 在调用类时自动触发 (return
self
给__init__
)
class Foo(object):
def __new__(cls, *args, **kwargs):
print('__new__')
return object.__new__(cls) # 产生了一个空对象
def __init__(self):
print('__init__')
foo_obj = Foo()
'''
__new__
__init__
'''
__init__
- 在创建完对象后自动触发
__init__
是实例化对象后触发的第一个方法(接收__new__
return 的self
)
__str__
- 在打印对象时自动触发
- 必须要有一个返回值, 该返回值必须是字符串类型
class Foo(object):
def __str__(self):
print('__str__在打印对象时自动触发')
return '__str__的返回值'
foo_obj = Foo()
print(foo_obj)
'''
__str__在打印对象时自动触发
__str__的返回值
'''
__call__
- 在对象被调用时自动触发
class Foo(object):
def __call__(self, *args, **kwargs):
print('__call__在对象被调用时自动触发')
foo_obj() # __call__在对象被调用时自动触发
__getattr__
- 在
对象.属性
时, 没有该属性时候自动触发
class Foo(object):
# 默认返回None
def __getattr__(self, item):
print('__getattr__会在对象.属性,且属性不存在时自动触发')
return item
foo_obj = Foo()
print(foo_obj.x)
'''
__getattr__会在对象.属性,且属性不存在时自动触发
x
'''
__setattr__
- 在
对象.属性=属性值
时自动触发
class Foo(object):
def __setattr__(self, key, value):
print('__setattr__在 对象.属性=属性值 时自动触发')
print(key, value)
foo_obj = Foo()
# 类中有__setattr__ 方法时, 如下操作只触发了__setattr__方法, 并不会给对象添加或修改属性
foo_obj.x = 1
'''
__setattr__在 对象.属性=属性值 时自动触发
x 1
'''
print(foo_obj.x) # AttributeError: 'Foo' object has no attribute 'x'
__del__
- 在对象被销毁后自动触发
class Foo(object):
def __del__(self):
print('__del__在对象被销毁后自动触发')
foo_obj = Foo()
print('对象被销毁前')
del foo_obj
print('程序最后的代码.')
'''
对象被销毁前
__del__在对象被销毁后自动触发
程序最后的代码
'''
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):
data = self.f.read()
print(f'''
当前文件: {self.file_name}
当前文件数据: {data}
''')
def __del__(self):
self.f.close()
print('关闭文件成功!')
f = Myfile('test_file.txt')
f.file_open()
f.file_read()
'''
当前文件: test_file.txt
当前文件数据: This is the content of test_file.txt
关闭文件成功!
'''
单例模式
概念
- 单例模式指的是某个类在整个系统中只存在一个实例的一种设计模式
目的
- 减少内存占用
- 加快运行性能 (只初始化一次)
实现方式
class File(object):
__instance = None
# # 方式1, 通过类的绑定方法实现
# @classmethod
# def singleton(cls, file_name):
# # 当类没有实例时
# if not cls.__instance:
# # 创建实例
# cls.__instance = cls(file_name)
# return cls.__instance
# 方式2, 通过__new__方法实现
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='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 file_read(self):
data = self.f.read()
print(f'''
当前文件: {self.file_name}
当前文件数据: {data}
''')
def close(self):
self.f.close()
# obj1 = File.singleton('test_file.txt')
# obj2 = File.singleton('test_file.txt')
# obj3 = File.singleton('test_file.txt')
obj1 = File('test_file.txt')
obj2 = File('test_file.txt')
obj3 = File('test_file.txt')
print(obj1)
print(obj2)
print(obj3)
'''
<__main__.File object at 0x0000000009F87A58>
<__main__.File object at 0x0000000009F87A58>
<__main__.File object at 0x0000000009F87A58>
'''