名称空间在继承中的顺序是什么?

2024-06-11 01:22:05 发布

您现在位置:Python中文网/ 问答频道 /正文

派生类可以隐式地访问其基类成员函数,除非我弄错了。派生类还可以通过如下方式在基类属性的调用前面加上前缀来访问它们:BaseClass.base\u属性. 但我似乎不明白派生类的实例如何使用基类的方法。示例:

class Visitor():
    """ Interface to Visitor

    provide an interface to visitors that
    perform an operation on a data collection """

    def visitProduce():
        pass
    def visitMeat():
        pass
    def visitBakedGoods():
        pass
    def visitDairy():
        pass
    def visitNonFood():
        pass



class PriceVisitor(Visitor):
    __cost = 0.0        # total cost of groceries

    def __init__(self):
        self.__cost = 0.0
    def visitProduce(self, p):
        self.__cost += p.price()
    def visitMeat(self, m):
        self.__cost += m.price()
    def visitBakedGoods(self, b):
        self.__cost += b.price()
    def visitDairy(self, d):
        self.__cost += d.price()
    def visitNonFood(self, nf):
        self.__cost += nf.price()


class Groceries():
    shopping_cart = []      # list of grocery items

    def Groceries(self):
        self.shopping_cart = []     
    def addProduce(self, p):
        pass
    def addMeat(self, m, lb):
        pass
    def addBakedGoods(self, b):
        pass
    def addDairy(self, d):
        pass
    def addNonFood(self, nf):
        pass
    def accept(self, v):
        pass
    def getShoppingCart(self):
        print(self.shopping_cart)
    def calculateCost(self, v):
        for item in self.shopping_cart:
            item.accept(v)
            item.details()
            print('Total cost is: $', v.__cost)



class Produce(Groceries):
    def addProduce(self):
        Groceries.shopping_cart.append(self)

    def accept(self, v):
        v.visitProduce(self)

    def price(self):
        return self.__price

    def details(self):
        print(self.__name, ' for: $', self.__price + '')



class Apples(Produce):
    __name = None
    __price = 3.25

    def __init__(self, name):
        self.__name = name

这是对苹果、农产品、食品和价格的测试

import VisitorPattern as vp

def main():
    # Visitor object
    my_visitor = vp.PriceVisitor()

    # Grocery object stores objects in its shopping_cart attribute
    my_groceries = vp.Groceries()

    # Add items
    red_apple = vp.Apples('red apple')
    gold_apple = vp.Apples('gold apple')
    red_apple.addProduce()
    gold_apple.addProduce()

    my_groceries.getShoppingCart()

    my_groceries.calculateCost(my_visitor)

if __name__ == '__main__':
    main()

现在,我的理解是,在构建Apple实例之后,它可以访问product的方法price()。用Apple类的实例调用这个方法将传递它自己的实例而不是self。然后,该程序返回属于调用该方法的实例(在本例中为Apple)的\uu price属性的值。但是,我得到一个错误:

C:\Users\josep_000\Documents\School\Summer 2015\Python Assignment 4>python test.
py
[<VisitorPattern.Apples object at 0x026E0830>, <VisitorPattern.Apples object at
0x026E0910>]
Traceback (most recent call last):
  File "test.py", line 23, in <module>
    main()
  File "test.py", line 20, in main
    my_groceries.calculateCost(my_visitor)
  File "C:\Users\josep_000\Documents\School\Summer 2015\Python Assignment 4\Visi
torPattern.py", line 60, in calculateCost
    item.accept(v)
  File "C:\Users\josep_000\Documents\School\Summer 2015\Python Assignment 4\Visi
torPattern.py", line 71, in accept
    v.visitProduce(self)
  File "C:\Users\josep_000\Documents\School\Summer 2015\Python Assignment 4\Visi
torPattern.py", line 28, in visitProduce
    self.__cost += p.price()
  File "C:\Users\josep_000\Documents\School\Summer 2015\Python Assignment 4\Visi
torPattern.py", line 74, in price
    return self.__price
AttributeError: 'Apples' object has no attribute '_Produce__price'

绑定和名称空间在继承中实际上是如何工作的?我可以只在product的每个派生类中编写price()方法,但这会破坏继承点。我想我的问题也源于名字弄乱,但仍然不知道如果我不把我的属性设置为“私有”会发生什么。澄清一下就好了。谢谢

编辑

我说杂货店的老板错了:

# Wrong way
def Groceries(self):   
    self.shopping_cart = []

# Should be
def __init__(self):
    self.__shopping_cart = []

一份全职工作和晚上的家庭作业的产物


Tags: nameinpyselfapplemydefpass
3条回答

What is the order of namespaces in inheritance?

Python使用方法解析顺序来查找绑定到该对象实例的方法。你知道吗

它还调用名称损坏,这就是为什么找不到方法_Produce__price。您试图使用.__price,但是当它被继承时,Python会将类的名称添加到名称的前面。不要使用两个下划线,将两个下划线改为一个,您的代码将按预期工作,并且您将始终查找._price,它不会调用名称mangling。你知道吗

更多信息请参见文档:

https://docs.python.org/2/tutorial/classes.html#private-variables-and-class-local-references

这并不是对所有问题的直接回答,但我希望下面的代码能为如何在Python中进行继承提供一些启示。你知道吗

class Produce(object):

    def __init__(self, name=None, price=None):
        self.__name = name
        self.__price = price

    def __str__(self):
        return self.__name

    @property
    def bulk_price(self):
        return self.__price * 100

class Apple(Produce):

    def __init__(self, name="Apple"):
        self.__name = name
        self.__price = 3.25
        super(self.__class__, self).__init__(self.__name, self.__price)

a = Apple("Gold Apple")
print a
print a.bulk_price
# Gold Apple
# 325.0

如您所见,我使nameprice在这两个类中都不可访问。这样,我就不能显式地调用它们,即a.__price。通过在子类中使用super,我可以避免进一步引用基类,同时仍然可以访问它的方法。你知道吗

我看到了你的错误,你的父母需要调用孩子的函数,但你没有转移到父母的孩子,所以它会得到的错误。现在我举个例子:

class A:
    def __init__(self, handler):
        self.a = 5
        self.real_handler = handler

    def get(self):
        print "value a = %d"%self.a
        self.real_handler.put()

class B(A):
    def __init__(self):
        A.__init__(self, self)    ##transport B to A
        self.b = 3

    def get(self):
        print "value b is %d"%self.b
        A.get(self)

    def put(self):
        self.b = 6
        print "value b change into %d"%self.b

if __name__=="__main__":
    b = B()
    b.get()

在父级B中,它将调用子级A的函数put()。我希望这能帮助你。你知道吗

相关问题 更多 >