如何让Python类方法同时支持静态调用与实例调用?以RSA的Fermat分解为例
问题
能否在Python中定义一个兼具静态方法(无需实例即可调用)与普通方法(通过实例调用)特性的类方法?
我正在开发一个RSA问题求解模块,现有RSA类的初始化代码如下:
class RSA: def __init__(self, n: int, e: int, c: int, p=None, q=None, phi=None): self.n = n self.e = e self.c = c self.p = p self.q = q assert p == None or gmpy2.is_prime(p), 'p must be prime' assert q == None or gmpy2.is_prime(q), 'q must be prime' self.phi = phi
类中用于分解n为p和q的fermat_factorization方法实现如下:
def fermat_factorization(self, n=None): if n == None: n = self.n t_ = gmpy2.isqrt(n)+1 counter = 0 t = t_ + counter temp = gmpy2.isqrt((t * t) - n) while((temp * temp) != ((t * t) - n)): counter += 1 t = t_ + counter temp = gmpy2.isqrt((t * t) - n) s = temp p = t + s q = t - s return p, q
当前实现无法满足需求,我希望该方法既能通过RSA.fermat_factorization(n)直接调用(传入大整数n),又能通过实例调用:
s1 = RSA(n, 65537, c) # c和n为大整数 p, q = s1.fermat_factorization() # 无需指定n,自动使用实例属性
解决方案
可以实现,通过@staticmethod装饰器结合参数类型判断即可兼容两种调用方式:
修改后的fermat_factorization方法代码如下:
class RSA: # 省略__init__代码... @staticmethod def fermat_factorization(n_or_self=None): # 处理实例调用:如果传入的是RSA实例,直接使用其n属性 if isinstance(n_or_self, RSA): n = n_or_self.n else: # 处理静态调用:必须传入n参数 n = n_or_self if n is None: raise ValueError("调用静态方法时必须传入n参数") # 原算法逻辑保持不变 t_ = gmpy2.isqrt(n)+1 counter = 0 t = t_ + counter temp = gmpy2.isqrt((t * t) - n) while((temp * temp) != ((t * t) - n)): counter += 1 t = t_ + counter temp = gmpy2.isqrt((t * t) - n) s = temp p = t + s q = t - s return p, q
调用验证
- 静态调用(无需实例):
p, q = RSA.fermat_factorization(123456789)
- 实例调用(自动使用实例属性):
s1 = RSA(123456789, 65537, 987654321) p, q = s1.fermat_factorization()
原理说明
- 当通过实例调用时,Python会自动把实例作为第一个参数传入方法,此时
n_or_self就是RSA实例,我们直接提取其n属性使用。 - 当通过类直接调用时,我们需要手动传入n参数,此时
n_or_self就是传入的整数n,直接使用即可;如果未传入n则抛出明确的错误提示。
内容的提问来源于stack exchange,提问作者Cheesewaffle
相关产品推荐
相关产品推荐

