这是一个纯Python特定的设计问题:
class MyClass(object):
...
def get_my_attr(self):
...
def set_my_attr(self, value):
...
Run Code Online (Sandbox Code Playgroud)
和
class MyClass(object):
...
@property
def my_attr(self):
...
@my_attr.setter
def my_attr(self, value):
...
Run Code Online (Sandbox Code Playgroud)
Python让我们可以这样做.如果你要设计一个Python程序,你会使用哪种方法?为什么?
我试图了解Python的描述符是什么以及它们对什么有用.但是,我没有成功.我理解它们是如何工作的,但这是我的疑惑.请考虑以下代码:
class Celsius(object):
def __init__(self, value=0.0):
self.value = float(value)
def __get__(self, instance, owner):
return self.value
def __set__(self, instance, value):
self.value = float(value)
class Temperature(object):
celsius = Celsius()
Run Code Online (Sandbox Code Playgroud)
为什么我需要描述符类?请使用此示例或您认为更好的示例进行说明.
什么是instance和owner这里?(in __get__).所以我的问题是,第三个参数的目的是什么?
我该怎么称呼/使用这个例子?
使用get/set似乎是Java中的常见做法(出于各种原因),但我几乎看不到使用它的Python代码.
为什么在Python中使用或避免使用get/set方法?
我试图在Python中访问函数外部的本地函数变量.所以,例如,
bye = ''
def hi():
global bye
something
something
bye = 5
sigh = 10
hi()
print bye
Run Code Online (Sandbox Code Playgroud)
以上工作正常.由于我想知道我是否可以bye在hi()不使用的情况下访问外部global bye,我试过:
def hi():
something
something
bye = 5
sigh = 10
return
hi()
x = hi()
print x.bye
Run Code Online (Sandbox Code Playgroud)
以上给出AttributeError: 'NoneType' object has no attribute 'bye'.
然后,我试过:
def hi():
something
something
bye = 5
sigh = 10
return bye
hi()
x = hi()
print x.bye
Run Code Online (Sandbox Code Playgroud)
这次它甚至没有出错.
那么,有没有办法在不使用全局变量的情况下访问函数(bye)之外的本地函数变量()hi()而不打印变量sigh?(问题编辑后包括 …
所以我读过你应该通过get或setter方法访问对象属性,比如object.get_this()或object.set_that(value).此代码是否适用于在类中定义的方法?或者它们仅用于对象实例.例如,这样做是不是惯用,
class test:
def __init__(self,value):
self.value = value
def get_value(self):
return self.value
def method(self):
return some_operation(self.value)
Run Code Online (Sandbox Code Playgroud)
与get_value()用于访问定义value为对象实例,还是应该get_value()也可以类方法中使用?
class test:
def __init__(self,value):
self.value = value
def get_value(self):
return self.value
def method(self):
return some_operation(self.get_value())
Run Code Online (Sandbox Code Playgroud) 好吧,我有几乎相同的问题,除了一个细节:我需要获取基类的私有值。代码:
class Parent(object):
def __init__(self):
self.__field = 13
class Child(Parent):
"""docstring for Child"""
def __init__(self):
super(Child, self).__init__()
def ChildMethodWhichUsingParentField(self):
return self.__field
if __name__ == '__main__':
c = Child()
c.ChildMethodWhichUsingParentField()
Run Code Online (Sandbox Code Playgroud)
口译输出:
Traceback (most recent call last):
File "foo.py", line 20, in <module>
c.ChildMethodWhichUsingParentField()
File "foo.py", line 16, in ChildMethodWhichUsingParentField
return self.__field
AttributeError: 'Child' object has no attribute '_Child__field'
Run Code Online (Sandbox Code Playgroud)
问题是口译员试图_Child__field在我需要时获取_Parent__field. 我可以使用 获得这个值@property,但它会阻止封装。我也可以解决这个问题,self._Parent__field但这是丑陋的,显然是糟糕的代码。还有其他方法吗?
我知道在python中使用getter和setter不是pythonic。而是应该使用属性装饰器。但我想知道以下场景 -
我有一个用几个实例属性初始化的类。然后稍后我需要向类添加其他实例属性。如果我不使用setter,那么我必须object.attribute = value在课外到处写。该类将没有self.attribute代码。当我需要跟踪类的属性时,这会不会成为问题(因为它们散布在类之外的代码中)?
我是Python的新手.所以,如果这是一个基本问题,请原谅我.我在互联网和SO上研究过这个话题,但我找不到解释.我正在使用Anaconda 3.6发行版.
我正在尝试为属性创建一个简单的getter和setter.我将引导你完成我得到的错误.
class Person:
def __init__(self,name):
self.name=name
bob = Person('Bob Smith')
print(bob.name)
Run Code Online (Sandbox Code Playgroud)
这打印出我同意的第一个名字,我没有覆盖print或getattribute方法.此外,这里没有房产.这是为了测试基本代码是否有效.
让我们修改代码来添加属性:
class Person:
def __init__(self,name):
self.name=name
@property
def name(self):
"name property docs"
print('fetch...')
return self.name
bob = Person('Bob Smith')
print(bob.name)
Run Code Online (Sandbox Code Playgroud)
一旦我在PyCharm中编写上面的代码,我就会得到一个黄色的灯泡图标,说明该变量必须是私有的.我不明白其理由.
忽略上面,如果我运行上面的代码,我得到:
Run Code Online (Sandbox Code Playgroud)Traceback (most recent call last): File "C:\..., in run_code exec(code_obj, self.user_global_ns, self.user_ns) File "<ipython-input-25-62e9a426d2a9>", line 2, in <module> bob = Person('Bob Smith') File "<ipython-input-24-6c55f4b7326f>", line 4, in __init__ self.name=name AttributeError: can't set attribute
现在,我研究了这个主题,我发现有两个修复(不知道为什么会这样):
修复#1: 将变量更改name为_name
class …Run Code Online (Sandbox Code Playgroud) 我有一个 python 类,用于一个具有属性名称、健康、力量、隐身、敏捷、武器和金钱的人物。我正在制作的游戏中有一家商店,用于增加具有特定项目的任何整数属性的值。每个整数属性都可以增加两个具有不同成本和增益强度的不同项目之一。我遇到的问题实际上是按数量增加属性并保存对象。
这是对象的代码:
class Figure:
def __init__(self, stats):
#create figure object
self.name = stats[0]
self.health = int(stats[1])
self.strength = int(stats[2])
self.stealth = int(stats[3])
self.agility = int(stats[4])
self.weapons = int(stats[5])
self.money = int(stats[6])
def show_person(self):
#show object attributes
print("\n\n{}\n\nHealth: {}\nStrength: {}\nStealth: {}\nCunning: {}\nWeapons: {}\nMoney: £{}".format(self.name.title(),self.health,self.strength,self.stealth,self.cunning,self.weapons, self.money))
def set_attr(self,attr,buff):
#increase character attribute by a variable amount
eval("self.{} = self.{} + {}".format(attr,attr,buff))
Run Code Online (Sandbox Code Playgroud)
我可能会将friend.set_attr("stealth",10)朋友的隐身值增加 10,其中朋友是包含这些 Figure 对象之一的变量,但会引发此错误:
File Computer Science\python\oop game.py", line 21, in set_attr
exec(eval("self.{} = self.{} + {}".format(attr,attr,buff)))
File …Run Code Online (Sandbox Code Playgroud) 我无法理解为什么 getter/setter 方法的名称必须与属性具有相同的名称。
我尝试在这里阅读亚伦·霍尔的答案,但我仍然找不到(或错过了)关于为什么我们必须使用各自名称的解释。
class Car(object):
def __init__(self, color='blue'):
self.color = color
self.current_model = 'Opel'
@property
def model(self, new_model):
return self.current_model
@model.setter
def model(self, new_model):
if new_model == 'Audi':
raise ValueError ('NO AUDI ALLOWED')
else:
self.current_model = new_model
# model = model.setter(models) but doing this works
@model.getter
def model(self):
return self.current_model
Run Code Online (Sandbox Code Playgroud)
编辑: 我发现令人困惑的是,如果我将方法重命名为:
@model.setter
def model_new(self, new_model):
if new_model == 'Audi':
raise ValueError ('NO AUDI ALLOWED')
else:
self.current_model = new_model
Run Code Online (Sandbox Code Playgroud)
我尝试运行:
audi = Car()
audi.model = 'BMW' # …Run Code Online (Sandbox Code Playgroud) python ×10
properties ×4
oop ×3
python-3.x ×3
class ×1
decorator ×1
descriptor ×1
getter ×1
inheritance ×1
setter ×1