让我想一想我想做什么:我有一个名为student
的结构或类,它包含像
int roll_no
和
int reg_no
如果用户希望在运行时添加char name
这样的新变量,该如何完成?
答案 0 :(得分:1)
基于单词“Structure”和变量声明,我猜这个问题是关于C的某些风格。完全这样做取决于语言,但是一般规则,如果编译语言(例如C / C ++,Java),这是不可能的。如果语言被解释(例如Python),这可能是可能的,如下所示:
class MyObj:
message = "Hi there"
a = MyObj() # Creating a new instance variable
a.name = "Bill" # Adding a new attribute
我们已将name
属性添加到a
对象仅,而不是整个类。我不确定你是怎么为整个班级做的。
但实际上,你问题的答案是“不要”。您应该考虑您的程序和您正在使用的对象,以了解您将要和不需要的字段。如果您希望在程序中的某个位置有一个名称字段,请将其放在类声明中。如果您不希望它具有对象创建的值,请使用合理的默认值null
。
根据您的评论,有几种方法可以解决这个问题。我仍然不完全清楚你想要什么,但我认为其中一个案例应该涵盖它。在我所知的语言中,Python在运行时是最灵活的:
在Python中,类只是另一种对象。类变量(也可以查看this question)属于类本身,并且由您创建的任何实例继承:
class MyObj:
a = 2 # A class variable
b = "a string" # Another one
ObjInstance = MyObj() # Creating an instance of this class
print ObjInstance.a # Output: "2"
ObjInstance.a = 3 # You can access and change the value of class variables *for this instance*
print MyObj.a, ObjInstance.a # Outputs "2 3". We've changed the value of a for the instance
MyObj.c = (3,4) # You can add a new class variable at runtime
# Any instance objects inherit the new variable, whether they already exist or not.
print MyObj.c, ObjInstance.c # Outputs "(3, 4) (3, 4)"
您可以使用此属性向类的每个实例添加属性,但在更改它们之前它们都将具有相同的值。如果要仅将属性添加到一个实例,可以执行以下操作:
ObjInstance.d = "I belong to ObjInstance!"
print ObjInstance.d # Output: "I belong to ObjInstance!"
print MyObj.d # Throws "AttributeError: class MyObj has no attribute 'd'"
使用Python的一个缺点是它可能有点慢。如果你想使用一种编译语言,它会稍微复杂一点,并且获得与上面提到的相同的功能将更加困难。但是,我认为这是可行的。这是我在Java中的表现。 C / C ++中的实现会有所不同。
Java的类属性(和方法)被调用(和声明)static
:
class MyObj {
public static int a = 2;
public static String b = "a string";
}
通常通过类名访问 static
个变量,就像在Python中一样。你可以通过一个实例获取它们,但我相信它会产生一个警告:
System.out.println(MyObj.a); //Outputs "2"
MyObj ObjInst = new MyObj();
System.out.println(ObjInst.a); //Outputs "2" with a warning. Probably.
您无法在运行时向Java对象添加属性:
ObjInst.c = "This will break"; // Throws some exception or other
但是,您可以使用HashMap
属性static
,可以在运行时添加条目,这些属性就像属性一样。 (这正是Python在幕后所做的。)例如:
class MyObj {
private HashMap<String, Object> att = new HashMap<String, Object>();
public void setAttribute(String name, Object value) {
att.put(name, value);
}
public Object getAttribute(String name) {
return att.get(name);
}
}
然后你可以做以下事情:
ObjInst.setAttribute("name", "Joe");
System.out.println(ObjInst.getAttribute("name"));
请注意,我上面没有声明att
static
,因此在这种情况下MyObj
类的每个实例都有此属性,但类本身才不是。如果我已将其声明为static
,则该类本身将具有此哈希的一个副本。如果你想变得非常花哨,可以将两种情况结合起来:
class MyObj {
private static HashMap<String, Object> classAtt = new HashMap<String, Object>();
private HashMap<String, Object> instAtt = new HashMap<String, Object>();
public static void setClassAttribute(String name, Object value) {
classAtt.put(name, value);
}
public void setInstAttribute(String name, Object value) {
instAtt.put(name, value);
}
public Object getAttribute(String name) {
// Check if this instance has the attribute first
if (this.instAtt.containsKey(name) {
return instAtt.get(name);
}
// Get the class value if not
else {
return classAtt.get(name);
}
}
}
我遗漏了一些细节,比如处理HashMap
没有你要求的价值的情况,但你可以弄明白该做什么。最后一点,您可以使用dict
在Python中完成我在Java中所做的工作,如果属性名称是字符串,那么这可能是个好主意。您可以在Python中将属性添加为字符串,但这有点难;查看有关反射的文档以获取更多信息。