将模块中的实例属性移动到模块

时间:2014-08-12 13:37:36

标签: python class init

我遇到了很麻烦,我确信这是一个简单的解决方法。虽然,我到处寻找,但我找不到我想要的东西。

我有三个模块, module1.py module2.py module3.py

例如,在 module1.py 中,我有一个初始化类,如下所示:

class MyClass():
    def __init__(self):
        self.name = ''
        self.age = 0

module2.py 中,我使用该类创建了一个实例,如下所示:

from module1 import MyClass
import module3 # this is where i keep my functions that i 
               # repeatedly use for better code management


me = MyClass()
me.name = "John"
me.age = module3.func_that_does_stuff()

module3.example_func(me.name, me.age)  # this function should manipulate the 
                                       # name and age lets say it turns john into 
                                       # rick, and 25 into 30

Module3.py

func_that_does_stuff():
    return 25

example_func(name, age):
    name = "rick"
    age = 30
    return name, age

就像我上面所说,在 module3 中我有功能,但这里是我遇到问题的地方。我可以将objectsme.nameme.age)传递给另一个模块中的函数,但它似乎不会更新me.nameme.age

所以当我尝试在模块2中打印时

print(me.name)
print(me.age)

我明白了:

self.name = "John"
self.age = 25

如何将对象的值传递给另一个模块,按照我认为合适的方式处理它们,并且能够更新self.name原始实例的self.ageme ??

希望这是有道理的。

3 个答案:

答案 0 :(得分:1)

以下是example_func的作用:

def example_func(name, age): # take two arguments
    name = "rick" # ignore first argument, assign string literal to name
    age = 30 # ignore second argument, assign integer literal to name
    return name, age # return new values

以及module2做了什么:

module3.example_func(me.name, me.age) # pass two objects (that get ignored)
                                      # and ignore the returned values

修改:

  1. 作为参数传递的(immutable!)对象;或
  2. 具有这些对象的属性的类实例。
  3. 您需要将这些返回的值分配回实例:

    me.name, me.age = module3.example_func(me.name, me.age)
    

    或者,让module3.example_func将一个MyClass实例作为参数,然后进行就地修改:

    def example_func(an_instance):
        an_instance.name = "rick"
        an_instance.age = 30
    

    但是,鉴于example_func似乎与MyClass的联系有多紧密,您至少应该考虑将它们放在同一个文件中。

答案 1 :(得分:1)

正如jonrsharpe的评论中所述,这里的问题是函数中的直接赋值,它在自己的名称空间中创建新变量。直接传递me实例而不是它的属性(它们是不可变对象)应该可以解决您的问题。

由于您的目的是访问和更改实例属性,请直接将me实例传递给该函数。

module3.example_func(me)

然后将您的函数修改为如下所示,以便直接修改实例属性。

example_func(me):
    me.name = "rick"
    me.age = 30

注意,我们跳过return,因为我们正在直接修改对象。

答案 2 :(得分:-1)

在Python中,即使是字符串或整数也是对象。但是,这些对象的行为与从类object继承的行为不同(请参阅immutable objects ...)。 例如:

>>> s = "Hello word"
>>> s.foo = 15
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
/local00/home/J91272/Bureau/<ipython console> in <module>()
AttributeError: 'str' object has no attribute 'foo'

然而,

>>> a = lambda x: 1
>>> a.foo = 36
>>> print a.foo
36

属性foo包含指向变量的指针。 当我们写a.foo = 36时,会创建一个新变量,foo的指针会在内存中设计新创建的值。

将变量a.foo传递给函数并不传递指针而是传递变量。 使用诸如par_a = 25之类的相等(对于已定义的函数func(par_a))修改此变量时,会创建一个新变量并修改par_a的指针。 但是a.foo的指针保持不变。

如果您想按照描述传递实例,最好传递整个对象,例如:

example_func(obj):
    obj.name = "rick"
    obj.age = 30
    return obj.name, obj.age

有时我们更喜欢只传递一些特定的参数。 对于从Python调用的非Pythonic函数,它甚至不是必需的。 在这种情况下,我可以建议一个掩码函数,如:

# Initial function that can not be modified
def example_func(name, age):
    name = "rick"
    age = 30
    return name, age

# Mask function that allows passing the object
def mask_function(obj):
    ret = example_func(obj.name, obj.age)
    obj.name, obj.age = ret
    return ret

如果有更多的Pythonic解决方案,我会感兴趣的!