突变体,一个用于访问时发生变化的Python库
项目描述
突变体,一个用于访问时发生变化的Python库
===========================================================
简而言之
--------
`mutants` 允许创建在访问时发生变化的Python对象。
它通过创建代理对象来工作
在每次访问时更改底层对象。
演示
----
```python
import random
import mutants
n = mutants.OnAccessMutant(0, lambda n: n + 1)
print(n) # 打印 1
print(n) # 打印 2
print(n) # 打印 3
class Duck
feathers = True
def quack(self)
print('quack')
class Wolf
teeth = 'sharp'
def quack(self)
print('no quack')
def random_animal()
return random.choice([Duck(), Wolf()])
randy = mutants.ImmutableMutant(random_animal)
randy.quack() # 打印 'quack' 或 'no quack'
randy.quack() # 打印 'quack' 或 'no quack'
print(hasattr(randy, 'feathers')) # 打印 'True' 或 'False'
randy.name = 'Randy'
print(hasattr(randy, 'name')) # 打印 'False', see below
def class_toggler(animal)
if isinstance(animal, Duck)
return Wolf
return Duck
tracy = mutants.ClassHopperMutant(Duck(), class_toggler)
tracy.quack() # 打印 'no quack' as it's a Wolf
tracy.quack() # 打印 'quack' as it's a Duck
print(tracy.teeth) # 打印 'sharp' as it's a Wolf
tracy.name = 'Tracy'
print(tracy.name) # 打印 'Tracy'
def class_extender(animal)
class SleepyAnimal(animal.__class__)
def quack(self)
super().quack()
print('zzz')
return SleepyAnimal
zetta = mutants.ClassHopperMutant(Duck(), class_extender)
zetta.quack() # 打印 'quack' and 'zzz'
```
详情
-------
根据您的需求,您可以选择
两种突变体之一:ImmutableMutant和ClassyMutant
或创建自定义的OnAccessMutant。
### OnAccessMutant
`OnAccessMutant` 是库的核心类。
它就像 `wrapt.ObjectProxy` 一样包装对象。
但在每次访问之前都会调用一个回调
并且可以修改或替换代理对象。
用法:`OnAccessMutant(initial_object, callable_mutator)`
其中:`callable_mutator(wrapped_object) -> new_wrapped_object`
### ImmutableMutant
`ImmutableMutant` 可以模仿不同的对象。
其构造函数接受一个可调用的对象。
在每次访问之前,这个可调用对象会被调用以提供一个对象
让 `ImmutableMutant` 来伪装。
用法:`ImmutableMutant(callable_returning_objects_to_be_proxied)`
修改 `ImmutableMutant` 可能是一个奇怪的想法,
因为它不记得它伪装的对象
并且可调用对象下次可能返回其他内容。
在这个纯 Python 实现中,它被实现为
```python
def ImmutableMutant(mutator)
return OnAccessMutant(None, lambda _: mutator())
```
未来的 C 扩展可能会为了性能而单独实现。
### ClassHopperMutant
`ClassHopper` 在每次访问时重新评估被包装对象的类。
它就像 `obj.__class__ = callable_returning_a_class()`,
但神奇的是在每次操作对象之前发生。
用法:`mutant.ClassHopper(initial_object, callable_returning_a_class)`
在这个纯 Python 实现中,它被实现为
```python
def ClassHopperMutant(initial_object, class_returning_callable, copy=True)
from copy import copy as _copy
def class_mutator(obj)
obj.__class__ = class_returning_callable(obj)
return obj
if copy
initial_object = _copy(initial_object)
return OnAccessMutant(initial_object, class_mutator)
```
未来的 C 扩展可能会为了性能而单独实现。
更多关于突变体
------------------
`mutants` 是为了满足另一个库 `hacks` 的需求而生的,
该库帮助修改对象、函数或类的行为,
堆叠这样的修改
并可以在运行时轻松切换 `当前活动的修改堆栈`。
查看它:https://github.com/t184256/hacks
`mutants` 与 `wrapt.ObjectProxy` 或 `lazy-object-proxy` 类似
但具有错误和灵活性,而不是延迟、缓存和性能。
CPython/Python 开发者,请给我们一些更干净的工具来完成我们的技巧!
`mutants` 目前处于 alpha 状态,
所以如果有什么东西出错了,请发送 pull 请求!
许可协议
-------
`mutants` 在 MIT 许可证的条款下分发;
见 [LICENSE.txt](LICENSE.txt)。
===========================================================
简而言之
--------
`mutants` 允许创建在访问时发生变化的Python对象。
它通过创建代理对象来工作
在每次访问时更改底层对象。
演示
----
```python
import random
import mutants
n = mutants.OnAccessMutant(0, lambda n: n + 1)
print(n) # 打印 1
print(n) # 打印 2
print(n) # 打印 3
class Duck
feathers = True
def quack(self)
print('quack')
class Wolf
teeth = 'sharp'
def quack(self)
print('no quack')
def random_animal()
return random.choice([Duck(), Wolf()])
randy = mutants.ImmutableMutant(random_animal)
randy.quack() # 打印 'quack' 或 'no quack'
randy.quack() # 打印 'quack' 或 'no quack'
print(hasattr(randy, 'feathers')) # 打印 'True' 或 'False'
randy.name = 'Randy'
print(hasattr(randy, 'name')) # 打印 'False', see below
def class_toggler(animal)
if isinstance(animal, Duck)
return Wolf
return Duck
tracy = mutants.ClassHopperMutant(Duck(), class_toggler)
tracy.quack() # 打印 'no quack' as it's a Wolf
tracy.quack() # 打印 'quack' as it's a Duck
print(tracy.teeth) # 打印 'sharp' as it's a Wolf
tracy.name = 'Tracy'
print(tracy.name) # 打印 'Tracy'
def class_extender(animal)
class SleepyAnimal(animal.__class__)
def quack(self)
super().quack()
print('zzz')
return SleepyAnimal
zetta = mutants.ClassHopperMutant(Duck(), class_extender)
zetta.quack() # 打印 'quack' and 'zzz'
```
详情
-------
根据您的需求,您可以选择
两种突变体之一:ImmutableMutant和ClassyMutant
或创建自定义的OnAccessMutant。
### OnAccessMutant
`OnAccessMutant` 是库的核心类。
它就像 `wrapt.ObjectProxy` 一样包装对象。
但在每次访问之前都会调用一个回调
并且可以修改或替换代理对象。
用法:`OnAccessMutant(initial_object, callable_mutator)`
其中:`callable_mutator(wrapped_object) -> new_wrapped_object`
### ImmutableMutant
`ImmutableMutant` 可以模仿不同的对象。
其构造函数接受一个可调用的对象。
在每次访问之前,这个可调用对象会被调用以提供一个对象
让 `ImmutableMutant` 来伪装。
用法:`ImmutableMutant(callable_returning_objects_to_be_proxied)`
修改 `ImmutableMutant` 可能是一个奇怪的想法,
因为它不记得它伪装的对象
并且可调用对象下次可能返回其他内容。
在这个纯 Python 实现中,它被实现为
```python
def ImmutableMutant(mutator)
return OnAccessMutant(None, lambda _: mutator())
```
未来的 C 扩展可能会为了性能而单独实现。
### ClassHopperMutant
`ClassHopper` 在每次访问时重新评估被包装对象的类。
它就像 `obj.__class__ = callable_returning_a_class()`,
但神奇的是在每次操作对象之前发生。
用法:`mutant.ClassHopper(initial_object, callable_returning_a_class)`
在这个纯 Python 实现中,它被实现为
```python
def ClassHopperMutant(initial_object, class_returning_callable, copy=True)
from copy import copy as _copy
def class_mutator(obj)
obj.__class__ = class_returning_callable(obj)
return obj
if copy
initial_object = _copy(initial_object)
return OnAccessMutant(initial_object, class_mutator)
```
未来的 C 扩展可能会为了性能而单独实现。
更多关于突变体
------------------
`mutants` 是为了满足另一个库 `hacks` 的需求而生的,
该库帮助修改对象、函数或类的行为,
堆叠这样的修改
并可以在运行时轻松切换 `当前活动的修改堆栈`。
查看它:https://github.com/t184256/hacks
`mutants` 与 `wrapt.ObjectProxy` 或 `lazy-object-proxy` 类似
但具有错误和灵活性,而不是延迟、缓存和性能。
CPython/Python 开发者,请给我们一些更干净的工具来完成我们的技巧!
`mutants` 目前处于 alpha 状态,
所以如果有什么东西出错了,请发送 pull 请求!
许可协议
-------
`mutants` 在 MIT 许可证的条款下分发;
见 [LICENSE.txt](LICENSE.txt)。
项目详情
关闭
mutants-0.0.2.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | de02f0134424b7fb79192eb33e5dd3c6f41132e79732ab7a782c353fd47a6f85 |
|
MD5 | 3e0a85a4dac383f2d27ae0cec01dfff0 |
|
BLAKE2b-256 | 84b8d7e37b1acd477bdf91e672705f58bc1465cac5cc2dc2e4efd7a4b44a4d9c |