Python 基类变量不存储由派生类设置的值
我是python新手。 基类/python文件(Base.py) 派生类(派生的.py) 当我执行Derived.py文件时,以下是输出: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
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语句吗?什么是设置?你能解释一下导入语句吗?什么是设置?