ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 02.01.2026

Просмотров: 2707

Скачиваний: 0

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

24. RESOURCES

24.6 Obtaining the Lineage of a Resource

pyramid.location.lineage() returns a generator representing the lineage of the location aware resource object.

The lineage() function returns the resource it is passed, then each parent of the resource, in order. For example, if the resource tree is composed like so:

1

class Thing(object): pass

2

 

 

3

thing1

= Thing()

4

thing2

= Thing()

5

thing2.__parent__ = thing1

 

 

 

Calling lineage(thing2) will return a generator. When we turn it into a list, we will get:

1

2

list(lineage(thing2))

[ <Thing object at thing2>, <Thing object at thing1> ]

The generator returned by lineage() first returns the resource it was passed unconditionally. Then, if the resource supplied a __parent__ attribute, it returns the resource represented by resource.__parent__. If that resource has a __parent__ attribute, return that resource’s parent, and so on, until the resource being inspected either has no __parent__ attribute or has a __parent__ attribute of None.

See the documentation for pyramid.location.lineage() for more information.

24.7Determining if a Resource is In The Lineage of Another Resource

Use the pyramid.location.inside() function to determine if one resource is in the lineage of another resource.

For example, if the resource tree is:

1

2

3

4

5

class Thing(object): pass

a = Thing()

b = Thing() b.__parent__ = a

268

24.8. FINDING THE ROOT RESOURCE

Calling inside(b, a) will return True, because b has a lineage that includes a. However, calling inside(a, b) will return False because a does not have a lineage that includes b.

The argument list for inside() is (resource1, resource2). resource1 is ‘inside’ resource2 if resource2 is a lineage ancestor of resource1. It is a lineage ancestor if its parent (or one of its parent’s parents, etc.) is an ancestor.

See pyramid.location.inside() for more information.

24.8 Finding the Root Resource

Use the pyramid.traversal.find_root() API to find the root resource. The root resource is the root resource of the resource tree. The API accepts a single argument: resource. This is a resource that is location aware. It can be any resource in the tree for which you want to find the root.

For example, if the resource tree is:

1 class Thing(object): pass

2

3 a = Thing()

4 b = Thing()

5 b.__parent__ = a

Calling find_root(b) will return a.

The root resource is also available as request.root within view callable code.

The presence or absence of a virtual root has no impact on the behavior of find_root(). The root object returned is always the physical root object.

24.9 Resources Which Implement Interfaces

Resources can optionally be made to implement an interface. An interface is used to tag a resource object with a “type” that can later be referred to within view configuration and by pyramid.traversal.find_interface().

Specifying an interface instead of a class as the context or containment predicate arguments within view configuration statements makes it possible to use a single view callable for more than one class of resource object. If your application is simple enough that you see no reason to want to do this, you can skip reading this section of the chapter.

For example, here’s some code which describes a blog entry which also declares that the blog entry implements an interface.

269


24. RESOURCES

1 import datetime

2 from zope.interface import implementer

3 from zope.interface import Interface

4

5 class IBlogEntry(Interface):

6pass

7

8 @implementer(IBlogEntry)

9 class BlogEntry(object):

10def __init__(self, title, body, author):

11self.title = title

12self.body = body

13self.author = author

14self.created = datetime.datetime.now()

This resource consists of two things: the class which defines the resource constructor as the class BlogEntry, and an interface attached to the class via an implementer class decorator using the IBlogEntry interface as its sole argument.

The interface object used must be an instance of a class that inherits from zope.interface.Interface.

A resource class may implement zero or more interfaces. You specify that a resource implements an interface by using the zope.interface.implementer() function as a class decorator. The above BlogEntry resource implements the IBlogEntry interface.

You can also specify that a particular resource instance provides an interface, as opposed to its class. When you declare that a class implements an interface, all instances of that class will also provide that interface. However, you can also just say that a single object provides the interface. To do so, use the zope.interface.directlyProvides() function:

1

import datetime

2

from zope.interface import directlyProvides

3

from zope.interface import Interface

4

 

5

class IBlogEntry(Interface):

6

pass

7

 

8

class BlogEntry(object):

9

def __init__(self, title, body, author):

10self.title = title

11self.body = body

12self.author = author

13self.created = datetime.datetime.now()

270



12 class BlogEntry(object):
13 def __init__(self, title, body, author): 14 self.title = title
15 self.body = body
16 self.author = author
17 self.created = datetime.datetime.now()
18
19 entry = BlogEntry(’title’, ’body’, ’author’) 20 directlyProvides(entry, IBlogEntry1)
21 alsoProvides(entry, IBlogEntry2)
zope.interface.alsoProvides() will augment the set of interfaces directly provided by an instance instead of overwriting them like zope.interface.directlyProvides() does.
For more information about how resource interfaces can be used by view configuration, see Using Resource Interfaces In View Configuration.
24.10 Finding a Resource With a Class or Interface in Lineage
Use the find_interface() API to locate a parent that is of a particular Python class, or which implements some interface.
For example, if your resource tree is composed as follows:
271

24.10. FINDING A RESOURCE WITH A CLASS OR INTERFACE IN LINEAGE

14

15

16

entry = BlogEntry(’title’, ’body’, ’author’) directlyProvides(entry, IBlogEntry)

zope.interface.directlyProvides() will replace any existing interface that was previously provided by an instance. If a resource object already has instance-level interface declarations that you don’t want to replace, use the zope.interface.alsoProvides() function:

1

import datetime

2

from zope.interface import alsoProvides

3

from zope.interface import directlyProvides

4

from zope.interface import Interface

5

 

6

class IBlogEntry1(Interface):

7pass

8

 

9

class IBlogEntry2(Interface):

10

pass

11

 


24. RESOURCES

1

2

3

4

5

6

class Thing1(object): pass class Thing2(object): pass

a = Thing1() b = Thing2()

b.__parent__ = a

Calling find_interface(a, Thing1) will return the a resource because a is of class Thing1 (the resource passed as the first argument is considered first, and is returned if the class or interface spec matches).

Calling find_interface(b, Thing1) will return the a resource because a is of class Thing1 and a is the first resource in b‘s lineage of this class.

Calling find_interface(b, Thing2) will return the b resource.

The second argument to find_interface may also be a interface instead of a class. If it is an interface, each resource in the lineage is checked to see if the resource implements the specificed interface (instead of seeing if the resource is of a class). See also Resources Which Implement Interfaces.

24.11 Pyramid API Functions That Act Against Resources

A resource object is used as the context provided to a view. See Traversal and URL Dispatch for more information about how a resource object becomes the context.

The APIs provided by pyramid.traversal are used against resource objects. These functions can be used to find the “path” of a resource, the root resource in a resource tree, or to generate a URL for a resource.

The APIs provided by pyramid.location are used against resources. These can be used to walk down a resource tree, or conveniently locate one resource “inside” another.

Some APIs in pyramid.security accept a resource object as a parameter. For example, the has_permission() API accepts a resource object as one of its arguments; the ACL is obtained from this resource or one of its ancestors. Other APIs in the pyramid.security module also accept context as an argument, and a context is always a resource.

272