【问题标题】:Call a function outside any method but inside a class?在任何方法之外但在类内部调用函数?
【发布时间】:2016-08-03 23:28:00
【问题描述】:

我正在尝试调用一个函数来初始化我的 global 类级变量。请注意,由于某种原因,我无法编写构造函数来完成这项工作。 (原因:我正在为 Tempest 写一个测试用例)

代码:

class my_class(ParentClass):
    username = "abc"
    password = "123"
    hostname = self._get_hostname() # Error: self is undefined
    hostname = _get_hostname()      # Error: _get_hostname is undefined

    def myFunct(self):
        ...
        ...

    def _get_hostname(self):
        ...
        ...

在 python 中甚至可以用类函数初始化 global 类级变量吗?

注1:我也试过在_get_hostname()函数写完之后再进行hostname初始化,但是没用。

注意 2: 我可以在如下函数中执行 hostname 初始化:

def myFunction(self):
    hostname = self._get_hostname()
    # do something with hostname
    ...

但这会破坏使用 global 类级变量的全部目的。我想在其他函数中使用类级变量重用

【问题讨论】:

  • 构造函数使用def __init__(self):,你得到的类定义后面的代码不是构造函数。
  • @xthestreams 亲爱的我已经提到我无法编写构造函数
  • @InamTaj 为什么不将_get_hostname(cls): 设为类方法,然后像使用@classmethod 装饰器一样?
  • 没有在类定义中设置全局变量的情况。类定义中的代码在其模块加载时进行评估,因此尝试在那里设置变量与在模块级别的类外部定义它们一样有效。
  • @Serdmanczyk 我把它们称为全球是错误的。我的意思是类级变量。我已经编辑了我的问题。

标签: python python-2.7 oop python-3.x global-variables


【解决方案1】:

您不能为尚不存在的实例调用实例方法。如果您希望它独立于任何实例,并且您调用的函数不需要来自实例的任何信息,您可以使用 @staticmethod 装饰器,以便您可以静态调用 get hostname。

【讨论】:

  • 当我尝试执行初始化时,@staticmethod 方法也会出现同样的问题。这就是我正在做的事情。 hostname = my_class._get_hostname()
  • 它应该只是 _get_hostname() 除非我弄错了,另外它不应该带一个 self 参数
【解决方案2】:

首先:它们不是全局变量;它们是变量。 (全局变量在模块范围内定义。)

如果_get_hostname() 根本没有使用 self,你可以做一些粗略的事情:确保在使用它之前定义它,然后用假的第一个参数调用它。

class my_class(ParentClass):
    def _get_hostname(self):
        ...
    hostname = _get_hostname(None)   # Doesn't matter what

这是有效的,因为当您在 class 语句中调用它时,您仍然可以将其视为常规函数。它只需要在使用之前定义,就像任何函数一样。

如果它确实需要引用一个对象(甚至只是类),这将不起作用,因为该类还不存在。您可以做的最好的事情是在class 语句之前定义一个不使用类本身的函数并调用它。 (这也是你会做的 如果上一个选项是可能的,但......令人反感。)

def _get_hostname():
    ...

class my_class(ParentClass):
    hostname = _get_hostname()

或推迟初始化类变量,直到定义class。在这种情况下,_get_hostname 可能应该被声明为静态方法或类方法,这样您就不必为了初始化类变量而实例化类。

class my_class(ParentClass):
    @classmethod
    def _get_hostname1(cls):
        ...

    @staticmethod
    def _get_hostname2():
        ...

my_class.hostname = my_class._get_hostname1()
my_class.hostname = my_class._get_hostname2()

【讨论】:

  • 这很不符合pythonic,有一个@staticmethod装饰器是有原因的
  • 我不知道_get_hostname1 究竟做了什么,这就是为什么我提到将其设为classmethod 的可能性。如果可行的话,我强烈推荐在上课之前定义的常规函数​​。
  • 我已经更正了类级变量而不是全局变量。我把它们称为全球是错误的。
  • @classmethod@staticmethod 方法出现同样的问题。
  • 你还没说你遇到了什么问题。
猜你喜欢
  • 1970-01-01
  • 2011-05-10
  • 2019-04-16
  • 1970-01-01
  • 2012-02-21
  • 1970-01-01
  • 2020-08-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多