如何通过python中的函数更改对象属性

时间:2019-09-11 19:58:15

标签: python function class variables attributes

我有一个类,并创建了它的两个实例object1和object2,我给每个称为“数字”的属性添加了一个属性,我希望能够选择将创建的函数应用于哪个类更改“数字”属性,我设法创建了函数,但是当我执行它仅在函数的本地级别上执行时,它不会将结果返回到原始的object1.number实例,我认为问题在于我放置了变量。

所以我希望我的全局object1.number属性在number_changer函数内部更改,然后能够在函数外部看到该更改。

我已经在代码中使用了打印功能来遵循该过程,而且看起来效果很好,只是无法更改全局属性

class ClassA():    
    pass


object1 = ClassA()    
object1.number = "0"    
object2 = ClassA()    
object2.number = "1"    


current_object = "object1"    
x = input("new number ")    

print(object1.number)    


def number_changer(object_name,new_number):    
    variable = object_name + ".number"    
    global object1    

    ref_obj_list = ["object1.number", "object2.number"]    
    real_obj_list = [object1.number, object2.number]    
    count = -1    
    for item in ref_obj_list:    
        count += 1    
        if variable == item:    
            real_obj_list[count]  = new_number    
            d = real_obj_list[count]    

            return d    




print(number_changer(current_object,x))    

print(object1.number)    

当我在输入中输入数字“ 5”时,结果是

0    
5    
0    

object1.number属性不会更改,或者至少不会在全局级别

4 个答案:

答案 0 :(得分:2)

在Python中,对象是通过引用传递的,因此,如果您在函数/方法中更改了该对象的任何属性,则无论是否使用global都将对其进行更改。

我在您的逻辑中看到的问题是,您从未更改过属性的值,应该执行以下操作:

object1.number = 123 # this is going to change that attribute no matter if you use the global keyword

答案 1 :(得分:1)

大多数代码都是多余的。如果将对象传递给函数并访问不存在的属性,则会出现错误。如果设置了属性,它将创建(如果不存在)或更改(如果已存在):

class A:
    pass 


a1 = A()
a2 = A()

def changer(o,newtext):
    try:
        o.text = o.text + newtext
    except AttributeError:            # happens if the attribute does not exist
        print(".text does not exist")

a1.text = "whatever"
a2.text = "never"

print(a1.text, a2.text)  # prints whats being set
changer(a1,"changed")    # changes a1.text
print(a1.text, a2.text)  # prints changed text

changer(A(),"hallo")  # prints the caught/handled exception - A() has no .text

输出:

whatever never
whateverchanged never
.text does not exist

执行此操作的“正常”方法是将text简单添加到该类中:

class A:
    def __init__(self):
        self.text = None

那样,它一直存在并且对于每个实例都是唯一的。

有关实例和(共享)类属性的说明,请参见What is the difference between class and instance attributes?


要通过用户输入选择对象,请使用字典:

myAs = {"A1":a1, "A2":a2}   # a1,a2 from above

print(a1.text, a2.text)    
whichOne = input("Which element to change? " +  repr(list(myAs.keys())))
if whichOne in myAs:
    changer( myAs[whichOne],"YeHaa")
    print(a1.text, a2.text)

输出:

whateverchanged never
Which element to change? ['A1', 'A2'] A2
whateverchanged neverYeHaa

答案 2 :(得分:0)

在您的函数中,使用以下行:

real_obj_list[count]  = new_number  

您没有更改实际对象的值,而只是更改了real_obj_list数组中的值。

我看不到使用简单的作业有什么问题:

object1.number = 1

(在函数中无处可见,因此该值未更新)。

但是,如果您要使用它的功能,@ PatrickArtner的答案几乎可以总结一下。

答案 3 :(得分:0)

如果我更改current_object的值,它将根据需要更改属性,希望我希望能够选择在哪个对象中应用属性更改器,这就是为什么我不能使用直接方式的原因,谢谢很多。

current_object = "a"    
def matcher(object):    
    ref_list = ["a","b","c"]    
    real_list = [a,b,c]    
   count = -1    
    for item in ref_list:    
        count += 1    
        if item == object:    
            d = real_list[count]    
            return d    


class A():    
    pass    

a = A()    
b = A()    
c = A()    

var = matcher(current_object)    

def changer(o,newtext):    
    o.text =  newtext    

a.text = "bye"    
b.text = "hello"    
c.text = "Dunno"    

print(a.text)    
print(b.text)    
print(c.text)    

changer(var,"works")    

print(a.text)    
print(b.text)    
print(c.text)