我经常从我的 Python 代码中得到未捕获的异常(错误),这些异常被描述为TypeErrors. 经过大量的实验和研究,我收集了以下示例(以及细微的变化):
TypeError: func() takes 0 positional arguments but 1 was given
TypeError: func() takes from 1 to 2 positional arguments but 3 were given
TypeError: func() got an unexpected keyword argument 'arg'
TypeError: func() missing 1 required positional argument: 'arg'
TypeError: func() missing 1 required keyword-only argument: 'arg'
TypeError: func() got multiple values for argument 'arg'
TypeError: MyClass() takes no arguments
TypeError: unsupported operand type(s) for +: 'int' and 'str'
TypeError: can only concatenate str …Run Code Online (Sandbox Code Playgroud) 我想创建一个使用类似于此的策略设计模式的类:
class C:
@staticmethod
def default_concrete_strategy():
print("default")
@staticmethod
def other_concrete_strategy():
print("other")
def __init__(self, strategy=C.default_concrete_strategy):
self.strategy = strategy
def execute(self):
self.strategy()
Run Code Online (Sandbox Code Playgroud)
这给出了错误:
NameError: name 'C' is not defined
Run Code Online (Sandbox Code Playgroud)
替换strategy=C.default_concrete_strategy为strategy=default_concrete_strategy将工作但是,默认情况下,策略实例变量将是静态方法对象而不是可调用方法.
TypeError: 'staticmethod' object is not callable
Run Code Online (Sandbox Code Playgroud)
如果我删除@staticmethod装饰器它会工作,但还有其他方法吗?我希望自己记录默认参数,以便其他人立即看到如何包含策略的示例.
此外,是否有更好的方法来公开策略而不是静态方法?我不认为实现完整的课程在这里有意义.
python static-methods strategy-pattern default-parameters python-3.x
我有一些python对象,其中有一些方法,我想在beggining进行一些检查,取决于此检查,方法的代码将运行,或者将引发execption.我不想在每个方法的开头复制"检查"代码,而是在做一个装饰器,我也希望装饰器嵌入到类本身中,因为它与它密切相关.所以基本上:
而不是这个
class A(object):
def a_method(self):
if self.check_var is True:
(some_code)
else:
raise Exception
Run Code Online (Sandbox Code Playgroud)
我想要这个
class A(object):
def decorator(function):
def function_wrapper(self, *args, **kwargs):
if self.check_var is True:
return function(self, *args, **kwargs)
else:
raise Exception
return function_wrapper
@decorator
def a_method(self):
(some_code)
Run Code Online (Sandbox Code Playgroud)
我的第一个问题是,我是否正确行事?或者,还有更好的方法.我有很多A类的方法需要进行此检查,所以这就是为什么我不想不必要地复制代码.
我的第二个问题是,如果我按照我描述的方式进行此操作,当我想从类A派生类并执行相同的装饰器检查时,我遇到了问题.我再次不想复制代码,因此我想重用基类A中的装饰器来对派生类中的执行进行检查.我读过关于将装饰器变成一个@classmethod但是当我这样做时,我能够在派生类中使用装饰器而不再在基类中使用!
所以基本上我想要这样的东西:
class A(object):
@classmethod #maybe
def decorator(function):
def function_wrapper(self, *args, **kwargs):
if self.check_var is True:
return function(self, *args, **kwargs)
else:
raise Exception
return function_wrapper
@decorator
def a_method(self):
(some_code)
class B(A):
@decorator
def b_method(self):
(some_code)
Run Code Online (Sandbox Code Playgroud)
有人知道有什么干净的方法吗?
鉴于班级
from __future__ import annotations
from typing import ClassVar, Dict, Final
import abc
class Cipher(abc.ABC):
@abc.abstractmethod
def encrypt(self, plaintext: str) -> str:
pass
@abc.abstractmethod
def decrypt(self, ciphertext: str) -> str:
pass
class VigenereCipher(Cipher):
@staticmethod
def rotate(n: int) -> str:
return string.ascii_uppercase[n:] + string.ascii_uppercase[:n]
_TABLE: Final[ClassVar[Dict[str, str]]] = dict({(chr(i + ord("A")), rotate(i)) for i in range(26)})
Run Code Online (Sandbox Code Playgroud)
编译失败(使用 3.8.0)
../cipher.py:19: in <module>
class VigenereCipher(Cipher):
../cipher.py:24: in VigenereCipher
_TABLE: Final[ClassVar[Dict[str, str]]] = dict({(chr(i + ord("A")), rotate(i)) for i in range(26)})
../cipher.py:24: …Run Code Online (Sandbox Code Playgroud) python static-methods decorator class-variables python-typing
假设我有一个带有静态方法的类,并且我希望将类属性设置为该方法返回的值:
class A:
@staticmethod
def foo():
return 12
baz = foo()
Run Code Online (Sandbox Code Playgroud)
但是这样做我得到一个错误:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in A
TypeError: 'staticmethod' object is not callable
Run Code Online (Sandbox Code Playgroud)
我找到了解决这个问题的方法:
class A:
class B:
@staticmethod
def foo():
return 2
baz = B.foo()
Run Code Online (Sandbox Code Playgroud)
但例如,如果我写:
class A:
class B:
@staticmethod
def foo():
return 2
class C:
baz = B.foo()
Run Code Online (Sandbox Code Playgroud)
我也收到一个错误:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 6, in …Run Code Online (Sandbox Code Playgroud) python ×5
class-method ×2
class ×1
debugging ×1
decorator ×1
python-3.x ×1
subclass ×1
typeerror ×1