Python 基类变量不存储由派生类设置的值

Python 基类变量不存储由派生类设置的值,python,python-2.x,Python,Python 2.x,我是python新手。 基类/python文件(Base.py) 派生类(派生的.py) 当我执行Derived.py文件时,以下是输出: SESSION_ID in derived: 10 SESSION_ID in base: 我希望m2()中设置的值反映在m1()中。因此,预期产出为: SESSION_ID in derived: 10 SESSION_ID in base: 10 您能帮忙吗?模块中的全局变量只是一个属性(即成员) 该模块的实体) 因此,当您使用import

我是python新手。 基类/python文件(Base.py)

派生类(派生的.py)

当我执行Derived.py文件时,以下是输出:

SESSION_ID in derived:  10
SESSION_ID in base:  
我希望m2()中设置的值反映在m1()中。因此,预期产出为:

SESSION_ID in derived:  10
SESSION_ID in base:  10

您能帮忙吗?

模块中的全局变量只是一个属性(即成员) 该模块的实体)

因此,当您使用
import*
时,将创建新的本地模块全局
会话ID
,因此基本中的会话ID不受您在派生模块中所做更改的影响

基本上,修改
base.SESSION\u ID
不需要在
Derived.py
中使用
global
语句,调整
import
就足够了,请参见下面的代码:

from settings import base


class Derived():
    def m2(self):
        base.SESSION_ID = 10
        print "SESSION_ID in derived: ", base.SESSION_ID

def main():
    c2 = Derived()
    c2.m2()
    base.m1()


if __name__ == "__main__":
    main()

模块中的全局变量只是一个属性(即成员 该模块的实体)

因此,当您使用
import*
时,将创建新的本地模块全局
会话ID
,因此基本中的会话ID不受您在派生模块中所做更改的影响

基本上,修改
base.SESSION\u ID
不需要在
Derived.py
中使用
global
语句,调整
import
就足够了,请参见下面的代码:

from settings import base


class Derived():
    def m2(self):
        base.SESSION_ID = 10
        print "SESSION_ID in derived: ", base.SESSION_ID

def main():
    c2 = Derived()
    c2.m2()
    base.m1()


if __name__ == "__main__":
    main()

您的
派生的
类不是从
Base.py
中的任何内容派生的。这里,您只是从
Base
中调用一个基本函数,而不是从
Derived
中调用

以下是Python3中的一个示例:

>>> class Base():
>>>   SESSION = 42
>>>
>>>   def print_session(self):
>>>     print("Base session : %d" % self.SESSION)
>>>
>>> class Derived(Base):
>>>   SESSION = 999
>>>
>>> d = Derived()
>>> d.print_session()
Base session : 999

您的
派生的
类不是从
Base.py
中的任何内容派生的。这里,您只是从
Base
中调用一个基本函数,而不是从
Derived
中调用

以下是Python3中的一个示例:

>>> class Base():
>>>   SESSION = 42
>>>
>>>   def print_session(self):
>>>     print("Base session : %d" % self.SESSION)
>>>
>>> class Derived(Base):
>>>   SESSION = 999
>>>
>>> d = Derived()
>>> d.print_session()
Base session : 999

如果可能的话,我会避免使用全局变量和类作用域变量。这些会使您的程序更难理解(如果有其他东西改变了您下面的全局状态,则很难注意到)和测试(您需要在每次测试之间重置所有全局状态;通常只创建新的空状态更容易)

我可以通过创建一个状态对象来重构这个示例:

class State:
  def __init__(self):
    self.session_id = ''
然后使其显式成为基类的一个属性:

class Base:
  def __init__(self, state):
    self.state = state

  def m1(self):
    print("SESSION_ID in base: " + str(self.state.session_id))

class Derived(Base):
  def m2(self):
    self.state.session_id = '10'
    print("SESSION_ID in derived: " + str(self.state.session_id))
然后在main函数中,需要显式创建state对象并将其传入

def main():
  state = State()
  c2 = Derived(state)
  c2.m2()
  c2.m1()
但是,至关重要的是,您的测试不需要担心状态泄漏

def test_m2():
  state = State()
  obj = Derived(state)
  obj.m2()
  assert state.session_id == '10'

def test_m1():
  state = State()
  obj = Base(state)
  obj.m1()
  # If the session ID was a global or a class variable,
  # you'd get a different result if m2() was called or not
  assert state.session_id == ''

如果可能的话,我会避免使用全局变量和类作用域变量。这些会使您的程序更难理解(如果有其他东西改变了您下面的全局状态,则很难注意到)和测试(您需要在每次测试之间重置所有全局状态;通常只创建新的空状态更容易)

我可以通过创建一个状态对象来重构这个示例:

class State:
  def __init__(self):
    self.session_id = ''
然后使其显式成为基类的一个属性:

class Base:
  def __init__(self, state):
    self.state = state

  def m1(self):
    print("SESSION_ID in base: " + str(self.state.session_id))

class Derived(Base):
  def m2(self):
    self.state.session_id = '10'
    print("SESSION_ID in derived: " + str(self.state.session_id))
然后在main函数中,需要显式创建state对象并将其传入

def main():
  state = State()
  c2 = Derived(state)
  c2.m2()
  c2.m1()
但是,至关重要的是,您的测试不需要担心状态泄漏

def test_m2():
  state = State()
  obj = Derived(state)
  obj.m2()
  assert state.session_id == '10'

def test_m1():
  state = State()
  obj = Base(state)
  obj.m1()
  # If the session ID was a global or a class variable,
  # you'd get a different result if m2() was called or not
  assert state.session_id == ''

没有称为“Base”的类,只有一个模块。我想您可能在某个地方看到过一个容易被误解的示例。Python中的
global
仅表示代码所在模块的全局性,而不是所有使用的模块。这意味着有两个
SESSION\u ID
变量,一个用于
Base.py
模块/脚本,另一个用于
Derived.py
脚本。顺便说一句,你的代码没有遵循中概述的命名约定,包括脚本/模块文件的命名,我强烈建议你花时间阅读并开始遵循。你
派生的
类不是从任何东西派生的。没有称为“Base”的类,只有一个模块。我想您可能在某个地方看到过一个容易被误解的示例。Python中的
global
仅表示代码所在模块的全局性,而不是所有使用的模块。这意味着有两个
SESSION\u ID
变量,一个用于
Base.py
模块/脚本,另一个用于
Derived.py
脚本。顺便说一句,你的代码没有遵循中概述的命名约定,包括脚本/模块文件的命名,我强烈建议你花时间阅读并开始遵循。你的
派生的
类不是从任何东西派生的。你能解释一下import语句吗?什么是设置?你能解释一下导入语句吗?什么是设置?