我创建了这样的Enum对象:
class Gender(Enum):
FEMALE = 'female'
MALE = 'male'
RANDOM = random.choice([FEMALE, MALE])
Run Code Online (Sandbox Code Playgroud)
我想每次都获得真正的随机值,但它不起作用:
>>> class Gender(Enum):
... MALE = 'male'
... FEMALE = 'female'
... RANDOM = choice([MALE, FEMALE])
...
>>> Gender.RANDOM
<Gender.MALE: 'male'>
>>> Gender.RANDOM
<Gender.MALE: 'male'>
>>> Gender.RANDOM
<Gender.MALE: 'male'>
>>> Gender.RANDOM
<Gender.MALE: 'male'>
Run Code Online (Sandbox Code Playgroud)
我也试过使用lambda,但看起来不太好,虽然它有效:
Gender.RANDOM()
Run Code Online (Sandbox Code Playgroud)
是否有其他方法可以每次获取随机值,而不使用lambda表达式?
我们使用这个枚举对象作为某个方法的参数的默认值,这就是为什么它应该是属性而不是函数,因为当我们使用Gender.FEMALE它时它不是一个函数,它是一个属性,也Gender.RANDOM应该是一个属性:
def full_name(gender=Gender.FEMALE):
...
def full_name(gender=Gender.RANDOM):
...
Run Code Online (Sandbox Code Playgroud) 首先,我理解一般来说装饰工作是如何工作的.而且我知道@staticmethod在签名中剥离实例参数
class C(object):
@staticmethod
def foo():
print 'foo'
C.foo //<function foo at 0x10efd4050>
C().foo //<function foo at 0x10efd4050>
Run Code Online (Sandbox Code Playgroud)
有效.
但是,我不明白如何staticmethod实现这一点的源代码.
在我看来,该包装方法时foo的staticmethod,实例staticmethod被实例化,那么一些神奇的发生,使C.foo()合法的.
那么......那些魔法会发生什么?做了staticmethod什么?
我知道关于SO的巨大话题,staticmethods但没有一个能解决我的疑虑.但也许我没有点击魔术关键词.如果是的话,请告诉我.
对于寻找staticmethod源代码的人,请参阅https://hg.python.org/cpython/file/c6880edaf6f3/Objects/funcobject.c
python static-methods decorator python-internals python-decorators
我有一类叫做Node一个具有importancesetter和getter,如下:
class Node:
@property
def importance(self):
return self._importance
@importance.setter
def importance(self, new_importance):
if new_importance is not None:
new_importance = check_type_and_clean(new_importance, int)
assert new_importance >= 1 and new_importance <= 10
self._importance = new_importance
Run Code Online (Sandbox Code Playgroud)
后来,我有一个Theorem继承自的类Node.就所涉及的而言,a Theorem和a 之间的唯一区别是必须具有至少一个.NodeimportanceTheoremimportance3
一个定理如何能继承的importance二传手,但增加的附加约束importance >= 3?
我试着这样做:
class Theorem(Node):
@importance.setter
def importance(self, new_importance):
self.importance = new_importance # hoping this would use the super() setter
assert self.importance >= 3
Run Code Online (Sandbox Code Playgroud) 你如何在包装 python 属性设置器时模拟它(即调用原始设置器)?最直接的方法是访问__set__,但它对属性是只读的,因此不起作用。
from unittest import TestCase
from unittest.mock import patch, PropertyMock
class SomeClass:
def __init__(self, value):
self._value = value
@property
def value(self):
return self._value + 1
@value.setter
def value(self, value):
self._value = value + 1
class TestSomeClass(TestCase):
def test_value_setter(self):
instance = SomeClass(0)
with patch.object(SomeClass.value, '__set__', wraps=SomeClass.value.__set__) as value_setter:
instance.value = 1
value_setter.assert_called_with(instance, 1)
self.assertEquals(instance.value, 3)
Run Code Online (Sandbox Code Playgroud)
new_callable=PropertyMock文档中也有,我已经尝试将它与它结合,wrap但还没有让它工作。
我正在阅读Fluent Python第19章>正确查看属性,我对以下单词感到困惑:
属性始终是类属性,但它们实际上管理类实例中的属性访问.
示例代码是:
class LineItem:
def __init__(self, description, weight, price):
self.description = description
self.weight = weight # <1>
self.price = price
def subtotal(self):
return self.weight * self.price
@property # <2>
def weight(self): # <3>
return self.__weight # <4>
@weight.setter # <5>
def weight(self, value):
if value > 0:
self.__weight = value # <6>
else:
raise ValueError('value must be > 0') # <7>
Run Code Online (Sandbox Code Playgroud)
根据我以前的经验,类属性属于类本身并由所有实例共享.但是在这里,weight,属性是一个实例方法,它返回的值在实例之间是不同的.如何成为类属性?不是所有类属性对于任何实例都应该是相同的吗?
我想我误解了一些东西,所以我希望得到正确的解释.谢谢!
我想创建一个具有某些属性的对象。我想动态添加它们。与向现有对象实例添加方法类似,但使用属性而不是方法。下面是一个简单的例子。
我喜欢动态创建:
class A():
@property
def a(self):
return self._a
@a.setter
def a(self, x):
self._a = 10*x
@property
def b(self):
return self._b
@b.setter
def b(self, x):
self._b = 10*x
Run Code Online (Sandbox Code Playgroud)
要使用方法来做到这一点,我会这样做:
class B():
def __init__(self):
for i in range(70,80):
self.__dict__[chr(i)] = types.MethodType(lambda self,x: x*i, self)
Run Code Online (Sandbox Code Playgroud)
对于我尝试过的属性:
class B():
def __init__(self):
for i in range(70,80):
def tmp(self, x):
self._x = i*x
self.__dict__[chr(i)] = property(fget=lambda self: self._i, fset=tmp)
Run Code Online (Sandbox Code Playgroud)
我也找到了types.DynamicClassAttribute,但我不确定这是否有帮助。
这里提出了一个相关问题,关于向类添加属性(在 python 2 中): Dynamically add @property in python。我不知道如何将其扩展到类的实例。
我是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) 我有一个类,它获取细节并使用信息填充类,如果它已经id使用details方法实例化了.如果它没有实例化,我希望它改为使用传入的参数details作为id并返回一个新的实例化对象.类似于以下内容:
f = Foo()
f.id = '123'
f.details()
Run Code Online (Sandbox Code Playgroud)
但也允许:
f = Foo.details(id='123')
Run Code Online (Sandbox Code Playgroud)
我可以使用相同的details方法来完成此任务吗?或者我是否需要创建两个单独的方法并制作一个@classmethod?如果我将一个声明为a @classmethod而另一个不声明,它们可以具有相同的名称吗?
我知道这是一个新手问题,这是一个基本的Python问题,但它是在Scrapy的背景下,我无法在任何地方找到答案.
当我运行这个机器人代码时:
import scrapy
from tutorial.items import DmozItem
class DmozSpider(scrapy.Spider):
name = "dmoz"
allowed_domains = ["lib-web.org"]
start_urls = [
"http://www.lib-web.org/united-states/public-libraries/michigan/"
]
count = 0
def increment(self):
global count
count += 1
def getCount(self):
global count
return count
def parse(self, response):
increment()
for sel in response.xpath('//div/div/div/ul/li'):
item = DmozItem()
item['title'] = sel.xpath('a/text()').extract()
item['link'] = sel.xpath('a/@href').extract()
item['desc'] = sel.xpath('p/text()').extract()
x = getCount()
print x
yield item
Run Code Online (Sandbox Code Playgroud)
DmozItem:
import scrapy
class DmozItem(scrapy.Item):
title = scrapy.Field()
link = scrapy.Field()
desc = scrapy.Field()
Run Code Online (Sandbox Code Playgroud)
我收到此错误:
File …Run Code Online (Sandbox Code Playgroud) python ×10
decorator ×2
properties ×2
python-3.x ×2
class-method ×1
enums ×1
inheritance ×1
lambda ×1
methods ×1
mocking ×1
oop ×1
python-2.7 ×1
random ×1
scrapy ×1
unit-testing ×1
web-scraping ×1