在Python中,特点自省是一种强壮的特性,它答应咱们在运行时检查和操作目标的特点。在本文中,咱们将讨论Python中的特点自省,并结合实际场景和代码来展现其用法。
1. 私有特点与拜访约束
Python中的私有特点是指以下划线开头的变量或办法,例如_name
或_method()
。尽管这种命名约定并非强制性的,只是一种常规,但它用于提示该特点或办法应该只在类内部运用,而不该该在外部直接拜访。
Python中的私有特点具有以下特点:
-
私有特点不能被外部直接拜访,但能够经过类内部的办法直接地拜访。
-
在类内部界说的办法能够拜访一切特点,包括私有特点,由于它们都在同一个效果域内。
-
子类无法承继父类的私有特点,但能够经过公有办法来拜访父类的私有特点。
接下来勇哥带你讨论怎么拜访和修正私有特点:
class YongeGe:
name= '勇哥' # 一般特点
_ager = 100 # 一般特点
__money = 109 # 私有特点
__money_empty__ = 1 # 不推荐做法
yongge = YongeGe()
print(yongge .name) # 输出: 勇哥
print(yongge ._ager ) # 输出: 100
print(yongge ._YongeGe__money ) # 输出: 109
print(yongge .__money_empty__ ) # 输出: 1
print(yongge .__money ) # 输出: AttributeError: 'YongeGe' object has no attribute '__money'
很显着看到 Python 中没有真实的私有特点
,实际上双下划线开头的特点被称号重整了,即将特点名转换为_ClassName__name
的办法,使其难以在外部被拜访。经过_YongGe__money
能够直接拜访私有特点__money
。可是一般不要用,就比如你爹告知你剩100块了,要省点花,你非要点个海底捞一把梭哈!
总之,Python的私有特点机制主要基于命名约定,其效果是约束特点的可见性和拜访性,然后提高代码的封装性和安全性。但是,需求留意的是,这种机制只是一种建议性的标准,并不能完全避免私有特点被拜访的可能性。
2. 特点自省与目标内部状况检查
在实际开发中,咱们经常需求检查目标的特点和办法,以便理解其内部状况。Python供给了几种特点自省的办法,使咱们能够方便地检查目标的特点。
2.1 运用__dict__
特点
__dict__
是目标的一个特点,它包括了目标的一切特点和办法。经过拜访__dict__
,咱们能够检查目标的内部状况。
例如,咱们界说了一个名为Person
的类,其中包括name
和age
两个特点,以及一个say_hello
办法。下面的代码展现了怎么经过拜访__dict__
来检查目标的特点和办法:
class YongeGe:
def __init__(self, name, money):
self.name = name
self.money= money
def money(self):
print(f"Hello, my name is {self.name}.I have {self.money} dollar ")
yongge = YongeGe("勇哥", "10")
yongge .money= "1010"
yongge .__dict__["age"] = "18"
输出成果为:
{'name': '勇哥', 'money': '1010', 'age': '18'}
咱们能够看到目标yongge
的特点和办法,包括name
、age
、money
以及money
办法。
需求留意的是,实例目标的__dict__
特点只能拜访和修正其自身的特点和办法,而无法拜访其所属类的特点和办法。如果需求拜访类的特点和办法,能够经过类的__dict__
特点来完成。
例如,咱们能够经过拜访Person.__dict__
来检查类Person
的一切特点和办法:
print(yongge .__dict__)
输出成果为:
{'__module__': '__main__', '__init__': <function YongeGe.__init__ at 0x0000017E50B9C5E0>, 'money': <function YongeGe.money at 0x0000017E50BBADC0>, '__dict__': <attribute '__dict__' of 'YongeGe' objects>, '__weakref__': <attribute '__weakref__' of 'YongeGe' objects>, '__doc__': None}
上述输出成果中,除了__init__
、say_hello
和__dict__
之外,还包括其他一些特别特点和办法。经过检查类的__dict__
,咱们能够获取到类的一切成员。
2.2 运用dir()
函数
除了拜访目标的__dict__
特点外,咱们还能够运用dir()
函数来检查目标的特点和办法。
dir()
函数回来一个包括目标一切特点和办法称号的列表。它不仅能够用于一般目标,还能够用于模块、类和内置类型等。
例如,下面的代码展现了怎么运用dir()
函数检查目标的特点和办法:
print(dir(p1))
输出成果为:
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__
str__', '__subclasshook__', '__weakref__', 'age', 'gender', 'hometown', 'name', 'say_hello']
从输出成果中,咱们能够看到目标p1
的特点和办法的称号列表。
2.3 运用__slots__
特点
在默许状况下,Python 类的实例会运用一个字典来存储它们的特点。这种办法关于特点很少的目标来说可能会糟蹋空间。特别是在创立大量实例时,这种空间耗费会变得更显着。
为了解决这个问题,咱们能够经过在类界说中运用__slots__
来掩盖默许的__dict__
行为。__slots__
是一个特别特点,它承受一个特点称号的序列,并且在每个实例中只为这些特点保留满足的空间来存储特点值。由于没有为每个实例创立__dict__
,所以能够节省空间。
class YongeGe:
# 界说 __slots__特点,让类实例只能绑定 __slots__中指定的特点,且不能增加其他特点
__slots__ = ('name', 'money')
def __init__(self, name_, money_):
self.name = name_
self.money = money_
if __name__ == '__main__':
yongge = YongeGe('勇哥', 100)
print(yongge.name)
setattr(yongge, 'new_attr', 100) # 输出:AttributeError: 'YongeGe' object has no attribute 'new_attr'
从上面的代码能够看到,在类中绑定了__slots__后,会约束类实例的灵敏性,不能动态增加新的特点,所以在运用这玩意的时分,要仔细想想要灵敏还是要内存?
2.4 自界说特点拜访
还能够经过界说一些特别办法来自界说类实例的特点拜访行为。这些特别办法能够操控特点的获取、设置和删去操作。
-
__getattribute__
办法:
获取一个特点时,Python 会首先调用该办法。咱们能够在这个办法中自界说特点的获取行为。例如,能够在办法中检查特点是否存在,并回来相应的值。def __getattribute__(self, data): value = super().__getattribute__(data) return value
-
__setattr__
办法:
设置一个特点时,Python 会调用该办法。咱们能够在这个办法中自界说特点的设置行为。例如,能够在办法中对特点进行类型检查,然后运用super().__setattr__()
办法设置特点的值。def __setattr__(self, key, value): super().__setattr__(key, value)
-
__delattr__
办法:
删去一个特点时,Python 会调用该办法。咱们能够在这个办法中自界说特点的删去行为。例如,能够在办法中执行一些清理操作或抛出反常。def __delattr__(self, item): super().__delattr__(item)
-
__getattr__
办法:
获取一个不存在的特点时,Python 会调用该办法。咱们能够在这个办法中自界说对不存在特点的处理逻辑。例如,能够回来默许值或许抛出反常。def __getattr__(self, item): pass
以上是一些常用的自界说特点拜访的办法。瞧瞧下面语句的执行顺序:
class MyClass:
def __init__(self):
self._data = {}
def __getattribute__(self, name):
# 自界说获取特点的行为
if name == 'attribute1':
return 'Custom Value'
elif name == 'attribute2':
return self._data[name] # 留意,这里会继续执行一次 __getattribute__
else:
return super().__getattribute__(name)
def __setattr__(self, name, value):
# 自界说设置特点的行为
if name == 'attribute2':
print("__setattr__", name, value)
self._data[name] = value + 10
else:
super().__setattr__(name, value)
def __delattr__(self, name):
# 自界说删去特点的行为
if name == 'attribute3':
self._data.pop(name, None)
else:
super().__delattr__(name)
def __getattr__(self, name):
# 处理不存在的特点
return f'Attribute "{name}" does not exist.'
if __name__ == '__main__':
obj = MyClass()
obj.attribute2 = 5
res = obj.attribute2
print(res) # 输出: __setattr__ attribute2 5 ;15
print(obj.attribute1) # 输出: Custom Value
del obj.attribute3
print(obj.attribute3) # 输出: Attribute "attribute3" does not exist.
在上面的示例中,咱们创立了一个名为MyClass
的类,其中界说了__getattribute__
、__setattr__
、
__delattr__
和__getattr__
四个办法来自界说特点拜访行为。经过在这些办法中编写相应的逻辑,咱们能够操控特点的获取、设置和删去操作,然后完成自界说的特点拜访行为。
经过自界说特点拜访,咱们能够更灵敏地操控类实例的特点操作,满足特定的需求,并增强代码的可读性和可维护性。
2.5 运用getattr()
、setattr()
和hasattr()
函数
除了检查目标的特点和办法外,咱们还能够运用getattr()
、setattr()
和hasattr()
函数来动态地拜访和修正目标的特点。
-
getattr(obj, attr)
函数用于获取目标obj
的特点attr
的值。 -
setattr(obj, attr, value)
函数用于设置目标obj
的特点attr
的值为value
。 -
hasattr(obj, attr)
函数用于检查目标obj
是否具有特点attr
,如果有回来True
,不然回来False
。
这些函数供给了一种灵敏的办法来操作目标的特点,特别适用于需求在运行时依据条件拜访或修正特点的状况。
例如,咱们能够经过调用getattr()
函数来获取目标的特点值:
name_value = getattr(yongge, "name")
print(name_value)
输出成果为:
勇哥
上述代码中,咱们运用getattr(yongge, "name")
来获取目标p1
的name
特点的值。
类似地,咱们能够运用setattr()
函数来设置目标的特点值:
setattr(yongge, "age", 40)
print(yongge.age)
输出成果为:
40
上述代码中,咱们运用setattr(yongge, "age", 40)
将目标yongge
的age
特点值设置为30
,然后再次打印yongge.age
,能够看到特点值已被修正。
别的,咱们还能够运用hasattr()
函数来检查目标是否具有某个特点:
has_money = hasattr(yongge, "money")
print(has_money)
输出成果为:
True
运用hasattr(yongge, "money")
检查目标yongge
是否具有money
特点,成果为True
,阐明目标具有该特点。
经过上述几种办法,咱们能够方便地进行特点自省,检查和修正目标的特点,然后更好地理解和操作代码。
3. 来点实际场景
假设咱们正在开发一个电商网站,需求处理用户购物车的相关逻辑。购物车中的产品信息以字典的办法存储在用户目标的特点中。咱们需求编写一个函数,用于核算购物车中产品的总价值。
界说一个User
类,包括一个cart
特点用于存储购物车中的产品信息:
class User:
def __init__(self, name):
self.name = name
self.cart = {}
def add_to_cart(self, item, price):
self.cart[item] = price
界说一个calculate_cart_value()
函数,用于核算购物车中产品的总价值。在函数内部,咱们能够经过特点自省来获取购物车中的产品信息,并核算总价值:
def calculate_cart_value(user):
cart = user.__dict__.get("cart", {})
total_value = sum(cart.values())
return total_value
在上述代码中,咱们运用user.__dict__.get("cart", {})
来获取购物车信息,如果用户目标中不存在cart
特点,则回来一个空字典。然后,咱们运用sum(cart.values())
来核算购物车中产品价格的总和。
下面是运用上述代码的示例:
# 创立用户目标
user = User("勇哥")
# 增加产品到购物车
user.add_to_cart("apple", 10)
user.add_to_cart("banana", 5)
user.add_to_cart("orange", 8)
# 核算购物车总价值
total_value = calculate_cart_value(user)
print(total_value) # 输出: 23
经过运用特点自省,咱们能够方便地拜访购物车信息,并核算总价值。特点自省还是挺重要的,面试也问得多,真实不会用也要背好飞机大炮的制造流程。可是这个玩意也不要乱用哟,频繁动态拜访,会有必定的功能开销哟~
总结
以上就是勇哥今日为各位小伙伴准备的内容,如有误,请包容并指出修正。如果你想了解更多关于Python自动化测验的常识和技巧,欢迎重视我:公众号\博客\CSDN\B站:测验玩家勇哥
;我会不定期地共享更多的精彩内容。感谢你的阅览和支持!
题外话,勇哥计划把新建的技能交流群,打造成一个活泼的高质量技能群。作业中遇到的技能问题,都能够在里面咨询大家,还有作业内推的机会。有爱好的小伙伴,欢迎加我(记住补白是进群还是报名学习)
勇哥,10年落魄测验老司机,技能栈偏python,现在在一家超大型房产公司担任自动化测验主管,日常作业比较繁杂,主要担任自动化测验,功能测验、软件质量办理及人员办理。作业之余专心于为粉丝进行简历修正、面试辅导、模拟面试、材料共享、1对1自动化测验教学辅导等副业开展。现在已服务十多位小伙伴,获得高薪offer。
往期精选文章:
python-Threading多线程之线程锁 |
Pytest 快速入门 |
pytest 前后置操作详谈 |
接口自动化之测验数据动态生成并替换 |
requests模块该怎么封装? |
最通俗易懂python操作数据库 |
python正则一篇搞掂 |
接口自动化怎么封装mysql操作 |
功能测验之必备常识 |
功能分析思路 |
Python + ChatGPT来完成一个智能对话的钉钉机器人 |
一文看懂python怎么执行cmd命令 |