为啥 Python 类初始化变量不能用于包导入中的类实例对象,但否则?

Posted

技术标签:

【中文标题】为啥 Python 类初始化变量不能用于包导入中的类实例对象,但否则?【英文标题】:Why is a Python class initialized variable not available to a class instance object from a package import but is otherwise?为什么 Python 类初始化变量不能用于包导入中的类实例对象,但否则? 【发布时间】:2018-07-27 19:30:07 【问题描述】:

嘿嘿...我正在学习装饰器。有趣的东西。我想我错过了一些东西,或者可能不是装饰器,而是我如何处理课程?当我在终端中执行此操作时,它可以工作:

class Client:
    """The main client."""

    def __init__(self, config, creds):
        """Initialize."""
        self.config = config
        self.creds = creds

    def context(func, *args, **kwargs):
        @wraps(func)
        def func_with_context(*args, **kwargs):
            print(f'contextualizing func.__name__')
            print(creds.user_name)
            return (args, kwargs)
        return func_with_context

    @context
    def test(self, creds):
        pass 

我有两个可以实例化并传入的包对象:

creds = mypackage.credentials.auto()
config = mypackage.Configuration()

然后当我这样做时:

client = Client(config, creds)
client.test('yo')
>>>contextualizing test
username@org
((<__main__.Client object at 0x101b66208>, 'yo'), )

但是当我从包本身这样做时,我得到了

import mypackage as mypackage
client = mypackage.Client(config, creds)
client.test('yo')
contextualizing test
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/dblack/Code/mypackage/mypackage/client.py", line 51, in func_with_context
    creds.user_name,
NameError: name 'creds' is not defined

为什么当我只声明一个类而不是在包命名空间中时这会起作用?

【问题讨论】:

你的print函数中不应该是self.creds吗? @ThomasKühn 我收到类似的错误:Traceback (most recent call last): File "&lt;stdin&gt;", line 1, in &lt;module&gt; File "/Users/dblack/Code/mypackage/mypackage/client.py", line 45, in func_with_context print(self.creds.user_name) NameError: name 'self' is not defined 因为您的方法参数中也漏掉了self @khelwood 我无法在该方法参数中声明 self (为什么它被删除)。通过将其添加到def context(self, func, *args, **kwargs): 我们得到:TypeError: context() missing 1 required positional argument: 'func' 但是你可以将它添加到func_with_context,因为它应该替换一个方法 【参考方案1】:

由于func_with_context 将代替方法,它应该有一个self 参数。然后在其中,您可以使用self.creds 引用creds 属性。

def context(func, *args, **kwargs):
    @wraps(func)
    def func_with_context(self, *args, **kwargs):
        print(f'contextualizing func.__name__')
        print(self.creds.user_name)
        return (args, kwargs)
    return func_with_context

【讨论】:

请注意,也没有理由在类中定义context,因为它只是一个常规函数。 @chepner 谢谢。这是一个精简版。它在我正在编写的模块中更有意义,但我想我明白你为什么这么说。

以上是关于为啥 Python 类初始化变量不能用于包导入中的类实例对象,但否则?的主要内容,如果未能解决你的问题,请参考以下文章

linux python 包安装了 为啥包不能导入

java 内部类为啥不能static

为啥在java中不能导入awt包

为啥 C++ 不能用“超类”类型的右值初始化“派生类”类型的变量?

Python中from module import * 导包方式下的__all__变量

1.IDEA明明已经导入了jar包为啥还是提示找不到类?