I am using PyDev to navigate the code of a relatively large Python projects. I want to view the hierarchy graph of the classes. I hit f4 to open the Hierarchy View.
But the view is completely empty, and there is nothing in it. I don't know why.
I just tested it here and it worked for me... To give an example:
Say you have:
class ClassA(object):
pass
class ClassB(ClassA):
pass
Now, with the cursor over 'ClassB' press 'F4': the hierarchy should be showing properly.
If it doesn't work for you, the first thing to check is if your code is under a 'source folder' in PyDev (i.e.: in the PYTHONPATH): See: http://www.pydev.org/manual_101_project_conf2.html for details.
Not sure if I was having the same problem as you... but I was able to get the hierarchy view to populate for some class objects, but only partial population for other class objects. Here's an example of one that wasn't working:
(notice the 'Parents' collection is blank despite being expanded)
Turns out the ones that were NOT working were due to me renaming some inherited class imported from some other module:
from module1 import ClassA as Class1
class ClassB(Class1):
pass
Understandably, this was confusing pydev. Sticking with the original names resolved the issue.
(sorry the images don't line up with the snippet.. but hopefully this helps someone)
Related
I read related posts but they didn't satisfy me.
Using tkinter i coded a class Musicsheet. Then I wrote classes of notes like wholeNote & halfNote, etc. After instantiaing MusicSheet followed by an instance of WholeNote, it looked ok, with the whole note on the music sheet. However, when I instantiated a half note the whole note had disappeared with just the half note on the sheet;it looks like halfNote had also instantiated ( sub classed?) a new music sheet thus previous notes/objects aren't there. This result in that the latest instance is always the only one on the sheet.
Thanks for the replies. Here are additional info:
class Musicsheet(Frame):
.......TCanvas initialization..
class WholeNote(MusicSheet):
......
class HalfNote(MusicSheet):
def __init__(self,x1,y1,x2,y2)
self.can.create_oval(x1,y1,x2,y2)
.....
more notes classes follow
Based on your current code:
Your note classes are derived from MusicSheet. I suppose you want the notes to be part of the sheet, not an instance of the Sheet. If you derive them from MusicSheet, the init of a Note would create a new instance of MusicSheet, not be added to the MusicSheet.
For Notes i recommend using Tkinter.CanvasItem class for inheritance.
(Type should be polygon for everything that is not a half/full rest or full note)
Using self.can.create_oval should be done in MusicSheet, not in Note Classes, as self.can should refer to the MusicSheet.
# models/__init__.py
from shared.cache import Cache
class modelA():
pass
class modelB():
pass
class modelC():
pass
# shared/cache.py
class Cache:
def methodA():
modelA.SomeStaticMethod()
Basically what I need is to access modelA from inside the Cache class.
If I try to import the models from cache.py, I get an error due to a circular reference error.
I know it seems a little bit weird but it's a very specific issue.
Is there anyway to do that?
You would usually restructure your files so that there is no circular reference error.
Simply answering your question, and usually seen as a workaround, you can import Cache on demand, only within the functions of models/__init__.py that make use of it. This may not be possible in this case, especially if Cache is used as a decorator at the module level.
See also this question.
I'm studying the code of jinja2.ext.InternationalizationExtension provided with Jinja2.
I know that tags can be added via the tags attribute; Jinja2 template parser will relinquish control and call user code when one of those strings is the first token in a {% %} block.
class InternationalizationExtension(Extension):
"""This extension adds gettext support to Jinja2."""
tags = set(['trans'])
I learned from the code that an extension can add attributes to the environment by calling Environment.extend; for jinja2.ext.InternationalizationExtension this is done in the __init__ method:
def __init__(self, environment):
Extension.__init__(self, environment)
environment.globals['_'] = _gettext_alias
environment.extend(
install_gettext_translations=self._install,
install_null_translations=self._install_null,
install_gettext_callables=self._install_callables,
uninstall_gettext_translations=self._uninstall,
extract_translations=self._extract,
newstyle_gettext=False
)
I know that custom filters are added by registering functions into Environment.filters:
def datetimeformat(value, format='%H:%M / %d-%m-%Y'):
return value.strftime(format)
environment.filters['datetimeformat'] = datetimeformat
The questions are:
Is it recommended that an extensions adds new filters, and not only tags and attributes to the environment? (The documentation suggests that this should be common practice)
Where in the extension subclass should this be done? In __init__ a reference to the environment is available, so in principle the above code could be put in the __init__ method.
Is it conceptually ok to do such thing in __init__? I personally don't like to alter objects states from within other objects' constructors, but in Jinja2 seems idiomatic enough to make it to an official extension (I'm talking about altering Environment.globals and calling Environment.extend from InternationalizationExtension.__init__).
Edit
A pattern to at least package filters nicely into a Python module. However this install function cannot be invoked from within a template (say, via a custom CallBlock created using an extension), because the environment should not be edited after the template has been instantiated.
def greet(value):
return "Hello %s!" % value
def curse(value):
return "Curse you, %s!" % value
def ohno(value):
return "Oh, No! %s!" % value
def install(env):
env.filters['greet'] = greet
env.filters['curse'] = curse
env.filters['ohno'] = ohno
Is it recommended that an extensions adds new filters, and not only tags and attributes to the environment?
Only if you need them. Otherwise, why overcomplicate your code? Filters are a very common use case for writing or extending other extensions, and the author most likely put that in there because they expect this to happen.
Where in the extension subclass should this be done?
It has to be done at call time, so if you don't directly put it in the __init__ you'll need to put it in a helper method called through __init__.
Is it conceptually ok to do such thing in __init__?
It's perfectly fine, so long as other users of your code can understand what it's doing. The simplest solution is usually the best.
I struggled with the title for this question so let me just lay out the code:
File A:
class SomeClass(Base):
__tablename__ = 'some_classes'
id = Column(Integer, primary_key=True)
my_awesome_property = Column(Unicode(255))
other_class = relationship('OtherClass', backref='some_class', uselist=False)
File B:
class OtherClass(Base):
__tablename__ = 'other_classes'
id = Column(Integer, primary_key=True)
my_sweet_property = Column(Unicode(255))
some_class_id = Column(ForeignKey('some_classes.id'))
Now, in many cases I would refer to both of these files from a "higher-order" file containing some functions like so:
Higher Order File:
from model.alpha import SomeClass
from model.bravo import OtherClass
from sqlalchemy.orm import sessionmaker
session = sessionmaker(bind=some_engine)()
def some_random_query():
return session.query(SomeClass).join(OtherClass).filter(OtherClass.my_sweet_property=='Mike Bayer\'s cat speaks SQL.').first()
So that's pretty normal, nothing wrong with that... until... I decide I want to a put a function into one of the lower-level files like File A (and avoid circular imports)
Back to File A:
# pretend I imported a session here
def frustrating_situation():
session.query(SomeClass).join(SomeClass.other_class).filter(SomeClass.other_class.my_sweet_property=='Get ready for an exception!').first()
This will throw this bad boy right here:
AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with SomeClass.other_class has an attribute 'my_sweet_property'
Now I suppose that makes sense given what I know of the internals of SQLAlchemy, but I also think from an API standpoint that statement should really work.
Here is how I worked around it:
session.query(SomeClass).join(SomeClass.other_class).filter(SomeClass.other_class.property.mapper.c.my_sweet_property == 'verbose, yet it works as desired').first()
So after all that, my question is really quite simple: Does anybody know a better / more idiomatic / proper / less dirty feeling way of doing this?
Suggestions welcome.
Side Note
For anyone who is wondering:
"Why not just import the class you want the reference to for the join/filter operation?"
There are a couple reasons why you might not want to / be able to import the class into the module where you are writing the query.
You have split up your class definitions across many files and decided to avoid circular imports by strictly not importing across same-level modules
You have decided to place functions that operate on 1 or more classes not currently defined or imported in the current module and do not wish to import them because they are not used for any other reason in the module (and see reason 1 again).
SomeClass.other_class.my_sweet_property
doesn't work in sqlalchemy. sorry.
You are referring to OtherClass, in this .filter() clause. how you arrive at that name is your business, but the clearest way, from the point of view of what each statement means and where the arguments come from is still just to import things.
edit: A common cause of problems with circular imports occurs when you try to import the names out of modules directly instead of just importing the modules. If you turn code that looks like:
from foo import Bar
def baz():
Bar.quux()
you'll have an import problem if foo is also trying to import this module (say, because it wants to use baz).
Fix it by importing only the module:
import foo
def baz()
foo.Bar.quux()
since foo.Bar is resolved later, only when baz() is called, you don't have any trouble when this module gets imported, since it doesn't actually try to use the contents of any of the modules it imports.
I want to have dict / list to which I can add values, just like models can be added to the admin register in django !
My attempt : (package -> __init__.py)
# Singleton object
# __init__.py (Package: pack)
class remember:
a = []
def add(data):
a.append[data]
def get():
return a
obj = remember()
# models1.py
import pack
pack.obj.add("data")
# models2.py
import pack
pack.obj.add("data2")
print pack.obj.get()
# We should get: ["data", "data2"]
# We get : ["data2"]
How to achieve the desired functionality ?
Some say that methods can do this if you don't need sub-classing, how to do this with methods ?
Update:
To be more clear :
Just like django admin register any one can import and register itself with admin, so that register is persisted between imports.
If it's a singleton you're after, have a look at this old blog post. It contains a link to a well documented implementation (here).
Don't. If you think you need a global you don't and you should reevaluate how you are approaching the problem because 99% of the time you're doing it wrong.
If you have a really good reason to do it perhaps thread_locals() will really solve the problem you're trying to solve. This allows you to set up thread level global data. Note: This is only slightly better than a true global and should in general be avoided, and it can cause you a lot of headaches.
If you're looking for a cross request "global" then you most likely want to look into storing values in memcached.