为什么不能以声明方式覆盖类名,例如使用不是有效标识符的类名?
>>> class Potato:
... __name__ = 'not Potato'
...
>>> Potato.__name__ # doesn't stick
'Potato'
>>> Potato().__name__ # .. but it's in the dict
'not Potato'
Run Code Online (Sandbox Code Playgroud)
我想也许这只是在类定义块完成后被覆盖的情况.但似乎这不是真的,因为名称是可写的,但显然没有在类dict中设置:
>>> Potato.__name__ = 'no really, not Potato'
>>> Potato.__name__ # works
'no really, not Potato'
>>> Potato().__name__ # but instances resolve it somewhere else
'not Potato'
>>> Potato.__dict__
mappingproxy({'__module__': '__main__',
'__name__': 'not Potato', # <--- setattr didn't change that
'__dict__': <attribute '__dict__' of 'no really, not Potato' objects>,
'__weakref__': <attribute …Run Code Online (Sandbox Code Playgroud) python metaclass python-datamodel python-descriptors python-object
我正在努力学习用Python编程,并专注于更好地处理如何使用标准模块和其他模块.dir函数在解释器中似乎非常强大,但我想知道我是否因为缺少OOP背景而遗漏了某些内容.使用S.Lotts一书,我决定使用他的Die类来学习有关类和实例的语法和用法的更多信息.
这是原始代码:
class Die(object):
''' simulate a six-sided die '''
def roll(self):
self.value=random.randrange(1,7)
return self.value
def getValue(self):
return self.value
Run Code Online (Sandbox Code Playgroud)
我正在看那个,在创建了一些实例后,我想知道单词value是否是某个关键字,以及在class语句中使用了word对象,所以我决定通过将类定义更改为以下内容来查找:
class Die():
''' simulate a six-sided die '''
def roll(self):
self.ban=random.randrange(1,7)
return self.ban
def getValue(self):
return self.ban
Run Code Online (Sandbox Code Playgroud)
这个变化向我展示了我从我的实例中获得了相同的行为,但是当我执行dir时,实例中缺少以下方法/属性:
'__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__',
'__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__',
_repr__', '__setattr__', '__str__', '__weakref__'
Run Code Online (Sandbox Code Playgroud)
我还想到,当我在一个实例上做了一个dir时,我有一个额外的关键字禁令,我最终想到的是我的实例的一个属性.这有助于我理解我可以使用d1.ban来访问我的实例的值.我可以弄清楚这是一个属性的唯一原因是我键入了d1.happy并得到了一个AttributeError 我发现d1.GetValue是一个附加到Die的方法,因为这就是解释器告诉我的.
因此,当我尝试使用像BeautifulSoup这样复杂但有用的模块时,如何在输入dir(实例)后知道列出的内容是我的实例的属性还是我的实例的方法.我需要知道这一点,因为这个问题让我觉得有了属性我调用方法的结果和方法我在我的实例上调用一个函数.
这个问题可能过于冗长,但确实有助于我更好地理解属性和方法之间的区别.具体来说,当我看到在我的Die类的实例上调用dir的结果时,我看到了这一点
['__doc__', '__module__', 'ban', 'getValue', 'roll']
Run Code Online (Sandbox Code Playgroud)
因此,通过查看列表中的属性和方法而不必诉诸试验和错误或者输入hasattr(myInstance,suspAttributeName)来查看它似乎很有用.
在发布我试过的问题之后
for each in …Run Code Online (Sandbox Code Playgroud) 我想获取正在装饰的函数的原始文件/脚本名称等.我怎样才能做到这一点?
def decorate(fn):
def wrapped():
return "scriptname: " + fn.scriptname?
return wrapped
Run Code Online (Sandbox Code Playgroud)
我尝试使用fn.__code__但是这给了我更多我需要的东西.我可以解析该字符串以获取函数名称,但是想知道是否有更优雅的方法来执行它
请考虑以下两个功能:
def f1():
return "potato"
f2 = lambda: "potato"
f2.__name__ = f2.__qualname__ = "f2"
Run Code Online (Sandbox Code Playgroud)
缺少对原始源代码的自省,是否有任何方法可以检测到f1是def和f2lambda?
>>> black_magic(f1)
"def"
>>> black_magic(f2)
"lambda"
Run Code Online (Sandbox Code Playgroud) 以下代码
import types
class A:
class D:
pass
class C:
pass
for d in dir(A):
if type(eval('A.'+d)) is types.ClassType:
print d
Run Code Online (Sandbox Code Playgroud)
输出
C
D
Run Code Online (Sandbox Code Playgroud)
如何按照代码中定义这些类的顺序输出?即
D
C
Run Code Online (Sandbox Code Playgroud)
除了使用inspect.getsource(A)并解析之外,还有什么方法吗?
好像__getattribute__只有2个参数(self, name).
但是,在实际代码中,我拦截的方法实际上是参数.
反正有没有访问这些论点?
谢谢,
查理
循环Python对象的方法并调用它们的正确方法是什么?
鉴于对象:
class SomeTest():
def something1(self):
print "something 1"
def something2(self):
print "something 2"
Run Code Online (Sandbox Code Playgroud) 我正在编写一个python类,它充当一个不可变的无限序列.
该类不使用生成器来访问此无限序列,而是根据__getitem__方法中的算法为序列中的任意索引生成值.
我很好奇处理__len__这种对象的方法的最佳方法是什么.理想情况下,我会回过头float("inf")来__len__.但是,在幕后len()调用对象__len__方法的函数需要一些特定的值.
如果__len__设置为返回float("inf")或decimal.Decimal("Infinity"),len()则通过引发TypeError来拒绝它.它还拒绝"-1"的值,这意味着序列是无限的.此外,当我试图用一个无边类,我碰巧早前撰文指出,确实在事实上继承int,len()无论出于何种原因返回0.
虽然让值只是"0"并不是一个很大的不便,虽然像这样的类很不寻常,但我仍然很想知道,有没有一种很好的方法来处理类的长度属性那是一个无限的序列?
在参考文献的数据模型中,作者花了很多精力来解释如何创建和操作用户定义的方法 :(参见http://docs.python.org/reference/datamodel.html#the-standard-type-hierarchy和roll下)
获取类的属性时(可能通过该类的实例),如果该属性是用户定义的函数对象,未绑定的用户定义的方法对象或类方法,则可以创建用户定义的方法对象宾语.当属性是用户定义的方法对象时,仅当从中检索它的类与存储在原始方法对象中的类相同或派生类时,才会创建新的方法对象; 否则,原始方法对象按原样使用.
那么未绑定的用户定义的方法对象和类方法对象之间的区别是什么?
当我调用str()具有重载__getattribute__方法的对象时,它似乎没有使用它,而是__str__直接调用。是否有其他一些我应该修改的功能或让它使用的方法__getattribute__?如果我__str__直接超载它会按预期运行,但这并不适合我的需求。
class A(object):
def __getattribute__(self, attr):
if attr == "__str__":
return lambda: "Hello"
return object.__getattribute__(self, attr)
x = A()
print(x)
print(str(x))
print(x.__str__())
Run Code Online (Sandbox Code Playgroud)
输出:
< main .A object at 0x000001FDF7AEA760>
< main .A object at 0x000001FDF7AEA760>
Hello
期望输出:
你好
你好
你好
python ×10
python-datamodel ×10
metaclass ×2
methods ×2
attributes ×1
getattribute ×1
infinite ×1
ironpython ×1
lambda ×1
object ×1
oop ×1
python-3.x ×1
reflection ×1