我希望能够在具有插槽优化的类中使用python描述符:
class C(object):
__slots__ = ['a']
a = MyDescriptor('a')
def __init__(self, val):
self.a = val
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是如何实现描述符类,以便能够在调用描述符对象的类实例中存储值.通常的解决方案看起来像下面的解决方案,但由于在C类中调用"slots"时不再定义"dict",因此无法工作:
class MyDescriptor(object):
__slots__ = ['name']
def __init__(self, name_):
self.name = name_
def __get__(self, instance, owner):
if self.name not in instance.__dict__:
raise AttributeError, self.name
return instance.__dict__[self.name]
def __set__(self, instance, value):
instance.__dict__[self.name] = value
Run Code Online (Sandbox Code Playgroud) 想象一个简单的文件夹结构:
my_folder/
__init__.py
funcs.py
tests/
test_funcs.py
Run Code Online (Sandbox Code Playgroud)
函数.py:
def f():
return 2
Run Code Online (Sandbox Code Playgroud)
__init__.py:
from funcs import f
Run Code Online (Sandbox Code Playgroud)
test_funcs.py:
from funcs import f
def test_f():
assert f() == 2
Run Code Online (Sandbox Code Playgroud)
这是文档中建议的方法之一: https://pytest.readthedocs.io/en/reorganize-docs/new-docs/user/directory_struct.html
但是当我从以下位置运行 pytest 时my_folder:
tests/test_funcs.py:1: in <module>
from funcs import f
E ModuleNotFoundError: No module named 'funcs'
Run Code Online (Sandbox Code Playgroud)
这很奇怪,因为我本以为pytest设置了它运行的路径,这样如果不手动处理就不会出现这些类型的错误。
文档也没有给出任何关于这一点的指示......他们只是说:
通常,您可以通过指向测试目录或模块来运行测试:
Run Code Online (Sandbox Code Playgroud)pytest tests/test_appmodule.py # for external test dirs pytest src/tests/test_appmodule.py # for inlined test dirs pytest src # run tests in all below test directories pytest # run all …
例如,我想有一个posint继承自的类int,但在调用时具有自定义行为isinstance():
>>> isinstance(1, int), isinstance(1, posint)
(True, True)
>>> isinstance(-1, int), isinstance(-1, posint)
(True, False)
Run Code Online (Sandbox Code Playgroud)
我先试过:
class posint(int):
def __instancecheck__(self, obj):
try:
obj >= 0
return True
except:
return False
Run Code Online (Sandbox Code Playgroud)
但是__instancecheck__必须在元类中声明。
所以我最终得到了这个沉重而丑陋的东西:
class NewType(type):
def __instancecheck__(self, obj):
try:
obj >= 0
return True
except:
return False
class posint(metaclass=NewType):
pass
Run Code Online (Sandbox Code Playgroud)
它有效,但它不是好的解决方案......不适用于任何其他检查,不支持继承......
在那之后,我设法实现了更好的东西:
class CheckedType(type):
def __instancecheck__(cls, obj):
if not all(isinstance(obj, base) for base in cls.mro()[1:-1]):
return False
return cls.__instancecheck__(obj)
class posint(int, metaclass=CheckedType):
@classmethod …Run Code Online (Sandbox Code Playgroud)