Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何转换一个";自定义类“-以编程方式将单例对象添加到python模块中?_Python_Module_Singleton - Fatal编程技术网

如何转换一个";自定义类“-以编程方式将单例对象添加到python模块中?

如何转换一个";自定义类“-以编程方式将单例对象添加到python模块中?,python,module,singleton,Python,Module,Singleton,我想通过编程将一个单例对象转换为Python模块,这样我就可以通过模块导入这个单例对象的方法,而不是作为对象属性访问它们,从而直接使用这个单例对象的方法。通过“编程方式”,我的意思是我不想将类方法显式复制粘贴到模块文件中。我需要某种变通方法,允许我将对象方法导入另一个模块的全局范围 如果有人能在这件事上帮助我,我将不胜感激 下面是一个基本示例,可以说明我的问题: mymodule.py main_as_is.py main_to_be.py 您可以使用标准模块使用的相同策略。该模块中的所有函数实

我想通过编程将一个单例对象转换为Python模块,这样我就可以通过模块导入这个单例对象的方法,而不是作为对象属性访问它们,从而直接使用这个单例对象的方法。通过“编程方式”,我的意思是我不想将类方法显式复制粘贴到模块文件中。我需要某种变通方法,允许我将对象方法导入另一个模块的全局范围

如果有人能在这件事上帮助我,我将不胜感激

下面是一个基本示例,可以说明我的问题:

mymodule.py main_as_is.py main_to_be.py
您可以使用标准模块使用的相同策略。该模块中的所有函数实际上都是
Random
类的“私有”实例的方法。这对于模块的大多数常见用途都很方便,尽管有时创建自己的
Random
实例很有用,这样您就可以拥有多个独立的随机流

我已经修改了您的代码来说明这种技术。我用一个前导下划线命名了这个类及其实例,因为这只是一个约定,Python并没有做任何事情来强制这种隐私

mymodule.py main_to_be.py 输出

myValue
顺便说一句,如果您只导入少量名称,或者从名称中可以清楚地知道它来自哪个模块(如数学模块函数和常量),并且不从许多模块导入,那么mymodule import method1、method2的
语法是可以的。否则最好使用这种语法

import mymodule as mm
# Call a method from the module
mm.method1()
通过这种方式,很明显哪些名称是本地名称,哪些名称是导入的,以及从何处导入的。当然,它需要更多的输入,但它使代码更具可读性。它消除了名称冲突的可能性

FWIW,这里有一种方法可以自动添加所有
\u myclass
方法,而无需显式列出它们(但请记住“显式优于隐式”)。在“mymodule.py”的末尾,添加以下内容,以代替
my_method=\u myclass.my_method

globals().update({k: getattr(_myclass, k) for k in _MyClass.__dict__ 
    if not k.startswith('__')})
我不喜欢推荐这种方法,因为它直接将项目注入
globals()
dict。请注意,该代码将添加所有类属性,而不仅仅是方法



在您的问题中,您讨论的是单例对象。我们通常不使用Python中的单体,许多OOP语言的程序员认为它们是反模式。有关详细信息,请参阅。对于这个应用程序,完全不需要使用单例。如果您只需要
\u MyClass
的一个实例,那么不要再创建另一个实例,只需使用
mymodule
为您创建的实例即可。但是,如果您的老板坚持您必须使用单例,请参阅示例代码。

请给我们一个包含24行左右的简化示例,以便我们确切了解您想要实现的目标。这样做的好处是什么?您不需要编写
someobj.thing
而是编写
somemodule.thing
。当然,除非您打算使用“star”导入等效项,但这通常不是一个好主意。请参阅和@PM2Ring:我的老板更喜欢过程式编程,所以他让我这么做。事实上,他希望像“从mymodule导入method1,method2”这样显式地导入方法。。。好处是您不必初始化对象,也不必每次使用方法时都键入“someobj;”你可能需要一个新老板:你的老板所说的“程序式编程”是什么意思?如果他反对OOP,我怀疑他会对Java风格的单例设计模式非常满意,这正是大多数反OOP的人所讨厌的。或者,如果他的意思是“不像Scheme那样的函数”(或Haskell),那么在他看来,使用类而不是闭包将是毫无意义的混淆。非常感谢。这种方法的问题是,我必须将类中的所有方法逐个分配给某个局部变量,因此我仍然需要复制粘贴所有内容。我想避免代码重复。@Jerry你是说你想避免在“mymodule.py”中对
\u myclass
的每个方法都必须执行
my\u method=\u myclass.my\u method
?@Jerry如果是这样的话,有一种方法可以做到,但它有点难看。FWIW,随机模块会一个接一个地进行明确的赋值,请参见模块的结尾。我同意这样一个事实,即这里没有太多可获得的东西,并且不应该用一些有争议的设计模式将事情过度复杂化;)我认为应该有一种简单的方法,在一个专门的过程模块或包中包含一些功能,这些模块或包最初是以OOP风格实现的,而不必强制使用OOP概念。我想我不应该在我的问题描述中使用术语“singleton”。最后,这种方法与Singleton模式的唯一共同点是,它使用一个类的单个实例来服务于特定的目的。关键的区别在于,这个实例不会在整个项目中被显式访问(我想这就是为什么Singleton模式成为一种设计模式,并且容易被误用的原因),但是它会被封装在一个模块中。
class _MyClass:
    """ This is my custom class """
    def my_method(self):
        return "myValue"

_myclass = _MyClass()
my_method = _myclass.my_method
from mymodule import my_method

print(my_method())       
myValue
import mymodule as mm
# Call a method from the module
mm.method1()
globals().update({k: getattr(_myclass, k) for k in _MyClass.__dict__ 
    if not k.startswith('__')})