也许我关于Python中的类实例化和变量赋值的问题听起来很普通,但是我在所寻找的任何地方都找不到答案。
class Car:
def __init__(self, motorhp = 0):
self._motorhp = motorhp
# getter method
def get_motorhp(self):
return self._motorhp
# setter method
def set_motorhp(self, y):
self._motorhp = y
myclass = Car()
myclass._motorhp = 440
myclass.horsepower=400
myclass.cilinders = 4
myclass.anystuff= 200
print(myclass.horsepower, myclass.cilinders,myclass._motorhp,myclass.anystuff)
运行后,我得到:
400 4 440 200
您可以看到,我从未使用类Car
中的setter和getter方法来修改motorhp
属性。为什么?因为我在没有下划线的情况下错误输入了属性motorhp
,所以我知道它可以正常工作!我很困惑!然后,我又创建了三个变量,分别为horsepower
,cilinders
和anystuff
,并且可以看到!我的意思是,我声明的任何内容[[myclass dot variable都有效!所以我只想了解为什么Python不抱怨myclass dot any,并且是否有避免的方法,或者这就是Python应该起作用的方法?
>>> class Car:
... pass
...
>>> car = Car()
>>> car.x=1
>>> car.x
1
>>> def func():
... print(func.x)
...
>>> func()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in func
AttributeError: 'function' object has no attribute 'x'
>>> func.x=1
>>> func()
1
对此有一些保护。使用双下划线会使实例变量变得模糊并且不太可能意外设置。__hp
内部变为_Car__hp
:
>>> class Car: ... def __init__(self,hp): ... self.__hp = hp ... def get_hp(self): ... return self.__hp ... >>> car = Car(10) >>> car.__hp Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Car' object has no attribute '__hp' >>> car.get_hp() 10 >>> car.__hp = 20 # You can still set an attribute with this name >>> car.get_hp() # but it isn't the same one due to the obfuscation. 10 >>> car.__hp # You can still read it directly. 20 >>> car._Car__hp # If you know the obfuscation trick you can find it. 10
但是,在变量/方法前加双分会对该变量/方法进行名称修饰。但是,如果需要(根据惯例,应避免使用而不使用),则可以使用以下语法来完成:
object_name._class_name__variable_name
示例:
class Car:
def __init__(self, motorhp = 0):
self.__motorhp = motorhp
# getter method
def get_motorhp(self):
return self.__motorhp
# setter method
def set_motorhp(self, y):
self.__motorhp = y
现在,如果我想像这样访问它:
c1.__motorhp
它将给您一个“ AttributeError”。但是,Python与Java,C ++等不同,因此,您可以直接将变量分配给对象。例如:
# Assign a new variable 'a' to object 'c1'- c1.a = 123 # Sanity check- c1.a # 123 # Delete variable 'a' from 'c1'- del c1.a c2 = Car(450) c2.get_motorhp() # 450 # Set a new value (not recommended)- c2._Car__motorhp = 556 c2.get_motorhp() # 556
但是,与Java,C ++,C#等不同,Python没有限制访问其任何实例方法和/或属性的系统。默认情况下,所有Python类成员都是'public'。