繁体   English   中英

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

[英]How to change an object atribute through a function in python

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

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

我已经在代码中使用了print函数来遵循该过程,而且看起来做得很好,只是它无法更改global属性

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属性不会更改,或者至少不会在全局级别更改

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

我在您的逻辑中看到的问题是,您永远不会更改属性的值,您应该执行以下操作:

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

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

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

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

请参阅类和实例属性之间的区别是什么? 用于解释实例和(共享)类属性


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

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

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

real_obj_list[count]  = new_number  

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

我看不到使用简单的分配有什么问题:

object1.number = 1

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

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

如果我更改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)    

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM