【问题标题】:__init__ method of python classpython类的__init__方法
【发布时间】:2017-05-08 12:25:58
【问题描述】:

我有一个名为 settings 的 python 类,它包括一个 __init__ 方法,用于设置一些值,如下所示:

class settings:
    global appkey
    global appversion
    def __init__(self):
        appkey = 1
        appversion = 1
        applicationname = "app1"
        applicationfile = "app.txt"

在另一个 python 文件(主脚本)中,我通过以下代码定义了我的设置类的一个实例:

import settings
from settings import settings
set = settings()
print set.appversion
print set.appkey
print set.applicationfile

但是当我运行我的主要 python 脚本时,我得到了这个错误:

AttributeError: settings instance has no attribute 'appversion'

我希望当我在这里定义一个类的实例时,设置类,它的 init 函数将被触发,我将为其属性设置值。

【问题讨论】:

  • 你应该写self.appkey = 1
  • with self 一切正常!
  • 另一个建议是在任何类变量上使用任何前缀_。因此,在init 中,您可能希望像这样初始化变量:self._appkey = 1。它确实对您没有太大的影响,但是如果您以后遇到问题,它可能会帮助人们理解您的代码,因为下划线 _ 是类变量的标志。 :)
  • self._ 是个好主意。谢谢@geostocker

标签: python class attributes initialization


【解决方案1】:

变量是您班级的__init__ 的本地变量。要将它们作为实例属性,您需要使用对实例的点引用将它们绑定到实例:

def __init__(self):
    self.appkey = 1
    ...

使用setattr 将属性绑定到/设置实例上的属性的同义词(但不那么冗长):

def __init__(self):
    setattr(self, 'appkey', 1)
    ...

另一方面,您不需要global 语句,因为您只想在实例上设置新属性;与全局命名空间无关。

您可以通过分析字节码轻松检查新 __init__ 的行为与之前的不同:

from dis import dis

class Settings(object):
   def __init__(self):
       self.appkey = 1  

dis(Settings.__init__)

3           0 LOAD_CONST               1 (1)
            2 LOAD_FAST                0 (self)
            4 STORE_ATTR               0 (appkey)
            6 LOAD_CONST               0 (None)
            8 RETURN_VALUE

注意我们不是像普通作业那样调用流行STORE_FAST,而是STORE_ATTR

【讨论】:

  • 对此的一点补充是在类变量上使用下划线前缀:self._appkey 以提高可读性并正确阐明它是类/私有变量。
【解决方案2】:

到目前为止,您只在 __init__() 方法中创建了“正常”变量。它们只能在该函数中本地访问。如果你想创建实例属性,你必须将它们分配给self

class settings:

    def __init__(self):
        self.appkey = 1
        self.appversion = 1
        self.applicationname = "app1"
        self.applicationfile = "app.txt"

【讨论】:

    【解决方案3】:

    我相信我前段时间遇到过类似的问题,不确定我的解决方案是否是最佳实践,但它确实实现了我的目标,即为每个用户创建一个日期时间变量,获取调查的开始时间,我只是需要在 Get 方法(调查开始)中声明变量 global,所以我可以将它传递给 Post 方法(调查结束)。然后我可以比较开始时间和结束时间,并计算每个参与者回答调查所花费的时间。经过审查,我看到了其他更简单的方法来达到相同的目标,无论如何,这是我使用的代码:

    类 EmView(DistanceMixin, RegistredIP, View):

    def __init__(self):
        self.dhms = datetime.now()
    
    def get(self, request):
    
    # DHMS ==> Date Time Hour Minutes Seconds survey started
    
        template_name = "survey/survey_section_a.html"
    
        global DHMS_START
        DHMS_START = self.dhms
    
            context_data = {
                "survey_form": survey_form,
                }
    
            return render(request, template_name, context_data)
    
    
     def post(self, request):
    
        dhms_start = DHMS_START
        dhms_end = datetime.now()
        dhms_survey_duration = dhms_end - dhms_start
    
     # other codes not included...
    

    【讨论】:

      猜你喜欢
      • 2011-08-03
      • 2011-11-06
      • 2015-04-19
      • 2017-08-28
      • 2017-12-13
      • 1970-01-01
      • 1970-01-01
      • 2015-11-27
      • 1970-01-01
      相关资源
      最近更新 更多